【问题标题】:Multiple thread with Autobahn, ApplicationRunner and ApplicationSessionAutobahn、ApplicationRunner 和 ApplicationSession 的多线程
【发布时间】:2023-12-28 03:06:01
【问题描述】:

python-running-autobahnpython-asyncio-websocket-server-in-a-separate-subproce

can-an-asyncio-event-loop-run-in-the-background-without-suspending-the-python-in

试图通过上面的两个链接解决我的问题,但我没有。

我有以下错误:RuntimeError: There is no current event loop in thread '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。谢谢。

【问题讨论】:

    标签: python multithreading python-3.x twisted


    【解决方案1】:

    一个单独的线程必须有它自己的事件循环。所以如果 poloniex_worker 需要监听一个 websocket,它需要自己的事件循环:

    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 的文件。那是我机器上 python3.5 > site-packages > autobahn > asyncio 中的 wamp.py。您可以像这样注释掉代码的信号处理部分:

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

    所有这些工作量很大。如果您不是绝对需要在与主线程不同的线程中运行 ApplicationSession,最好只在主线程中运行 ApplicationSession。

    【讨论】: