Многопоточность с автобаном, ApplicationRunner и ApplicationSession

Python-обкатка autobahnpython-asyncio-WebSocket-сервер-в-отдельном-subproce

может-ан-asyncio-событие-петля-бежать-в-фон-без-суспендирующие-на-питон-в

Пытался решить мою проблему с помощью этих двух ссылок выше, но у меня нет.

У меня следующая ошибка: RuntimeError: В потоке 'Thread-1' нет текущего цикла событий.

Вот пример кода (Python 3):

from autobahn.asyncio.wamp import ApplicationSession
from autobahn.asyncio.wamp import ApplicationRunner
from asyncio import coroutine
import time
import threading


class PoloniexWebsocket(ApplicationSession):

    def onConnect(self):
        self.join(self.config.realm)

    @coroutine
    def onJoin(self, details):

        def on_ticker(*args):
            print(args)

        try:
            yield from self.subscribe(on_ticker, 'ticker')

        except Exception as e:
            print("Could not subscribe to topic:", e)


def poloniex_worker():
    runner = ApplicationRunner("wss://api.poloniex.com:443", "realm1")
    runner.run(PoloniexWebsocket)


def other_worker():
    while True:
        print('Thank you')
        time.sleep(2)


if __name__ == "__main__":
    polo_worker = threading.Thread(None, poloniex_worker, None, (), {})
    thank_worker = threading.Thread(None, other_worker, None, (), {})

    polo_worker.start()
    thank_worker.start()

    polo_worker.join()
    thank_worker.join()

Итак, моя конечная цель - запустить 2 потока в начале. Только один должен использовать ApplicationSession и ApplicationRunner. Спасибо.

1 ответ

Отдельный поток должен иметь свой собственный цикл обработки событий. Так что если poloniex_worker нужно прослушивать веб-сокет, ему нужен собственный цикл обработки событий:

def poloniex_worker():
    asyncio.set_event_loop(asyncio.new_event_loop())
    runner = ApplicationRunner("wss://api.poloniex.com:443", "realm1")
    runner.run(PoloniexWebsocket)

Но если вы работаете на Unix-машине, вы столкнетесь с другой ошибкой, если попытаетесь это сделать. Autobahn asyncio использует сигналы Unix, но эти сигналы Unix работают только в основном потоке. Вы можете просто отключить сигналы Unix, если не планируете их использовать. Для этого вам нужно перейти в файл, где определен ApplicationRunner. Это wamp.py в python3.5 > site-packages > autobahn > asyncio на моей машине. Вы можете закомментировать секцию обработки сигналов в коде так:

# try:
#     loop.add_signal_handler(signal.SIGTERM, loop.stop)
# except NotImplementedError:
#     # signals are not available on Windows
#     pass

Все это очень много работы. Если вам абсолютно не нужно запускать ApplicationSession в отдельном потоке от основного потока, лучше просто запустить ApplicationSession в основном потоке.

Другие вопросы по тегам