我有一个简单的 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/