Многопоточность с автобаном, 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 в основном потоке.