线程中的python3 websocket

标签 python multithreading websocket

我有一个简单的 python tkinter gui,只有几个按钮。当按下按钮时,我想做的就是启动 websocket 连接并开始接收。我可以正常运行代码,但是一旦尝试将其放入线程中,就会出现错误

RuntimeError: There is no current event loop in thread

所以首先尝试:
import websockets
websocket = websockets.connect(uri, ssl = True)
websocket.recv()

我得到错误
"Connect object has no attribute 'recv'"

当我以不同的方式运行它时,这很奇怪我没有得到那个错误
当我完全按照文档
   def run_websockets2(self):
        async def hello():
            uri = Websocket_Feed
            # with websockets.connect(uri, ssl=True) as websocket:
            socket = await websockets.connect(uri, ssl=True)
            self.web_socket = socket
            while self.running:
                greeting = await socket.recv()
                print(f"< {greeting}")
        asyncio.get_event_loop().run_until_complete(hello())

只要我调用“websockets2()”,它就可以工作。但如果我尝试做
self.websocket_thread = threading.Thread(target=self.run_websockets2, args=())
self.websocket_thread.start()

我得到错误
RuntimeError: There is no current event loop in thread 'web_sockets'

当我使整个函数非异步时,我得到一个错误
def run_websockets(self):
    uri = Websocket_Feed
    # with websockets.connect(uri, ssl=True) as websocket:
    socket = websockets.connect(uri, ssl=True)
    self.web_socket = socket
    while self.running:
        greeting = socket.recv()
        print(f"< {greeting}")

我得到错误
RuntimeError:线程“web_sockets”中没有当前事件循环。在
socket = websockets.connect(uri, ssl=True)

我不明白为什么我不能简单地在线程中运行这些非异步。任何帮助是极大的赞赏

最佳答案

您在这里有几个不同的错误,这使图片有些困惑。首先,关于:

 "Connect object has no attribute 'recv'"

...这只是说websocket对象没有名为 recv 的方法

您遇到的主要问题是尝试调用 run_websockets2()从一个衍生的线程。 IE。从主线程调用此方法有效,但从新线程调用此方法失败。

这是预期的行为。这是因为在衍生线程(即主线程以外的线程)中,没有定义异步事件循环。但是为了方便起见,在主线程中定义了一个。因此 asyncio 知道您是从衍生线程还是主线程调用,并且行为不同。有关详细说明,请参阅此答案。 Why asyncio.get_event_loop method checks if the current thread is the main thread?

要解决您的问题,您可以为每个生成的线程创建一个新的事件循环,以便代码变为:
event_loop = asyncio.new_event_loop()
event_loop.run_until_complete(hello())

代替
asyncio.get_event_loop().run_until_complete(hello())

或者,您可以存储 event_loop在一个共同的地方,并允许所有派生的线程重用该事件循环。

关于线程中的python3 websocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58617631/

相关文章:

python - 使用 Python 比较两个 sqlite 数据库

sockets - 如何模拟本地服务器上的网络崩溃?

websocket - socket.io 中的用户存在 'room'

javascript - Spring WebSocket 返回未记录的 403

python - 从日期时间获取一年中的小时

python - 将报告格式转换为Python数据集

python - 使用 twisted.enterprise.adbapi 处理 'database is locked' 错误的正确和最佳方法

objective-c - 是否可以在操作系统或编程语言级别强制执行无共享多线程? (OSX, Objective-C )

java - 如何中断 Java 中的一系列程序?

c - 如何使用线程读写串口数据