Python 3.5 Asyncio和多个websocket服务器

u7up0aaq  于 2022-12-01  发布在  Python
关注(0)|答案(1)|浏览(201)

我在Ubuntu上使用Python websockets 4.0.1。我希望有2个websockets服务器运行。我能够通过创建2个线程和每个线程的独立事件循环来使其“类工作”。通过“类工作”,我的意思是两个websockets都工作并有响应大约30秒,然后其中一个停止。我必须重新启动这个过程才能让它们都重新工作。如果我只运行这两个线程中的一个或另一个,那么单个websocket将永远工作。
我做错了什么,我怎么能有2个websockets工作永远与asyncio?

# Start VL WebSocket Task
class vlWebSocketTask (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        # Main while loops
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        while True:
            try:
                print("Starting VL WebSocket Server...")
                startVLServer = websockets.serve(vlWebsocketServer, '192.168.1.3', 8777)
                asyncio.get_event_loop().run_until_complete(startVLServer)  
                asyncio.get_event_loop().run_forever()
            except Exception as ex:
                print(ex)
            time.sleep(5)

# Start IR WebSocket Task
class irWebSocketTask (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
    def run(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        while True:
            try:
                print("Starting IR WebSocket Server...")
                startIRServer = websockets.serve(irWebsocketServer, '192.168.1.3', 8555)
                asyncio.get_event_loop().run_until_complete(startIRServer)  
                asyncio.get_event_loop().run_forever()
            except Exception as ex:
                print(ex)
            time.sleep(5)
        
# Initialize VL WebSocket Task
#VLWebSocketTask = vlWebSocketTask()
#VLWebSocketTask.start()
        
# Initialize IR WebSocket Task
IRWebSocketTask = irWebSocketTask()
IRWebSocketTask.start()
vhmi4jdf

vhmi4jdf1#

你不需要线程来运行多个asyncio任务--允许多个代理共享同一个事件循环是asyncio的强项。

loop = asyncio.new_event_loop()
loop.run_until_complete(websockets.serve(vlWebsocketServer, '192.168.1.3', 8777))
loop.run_until_complete(websockets.serve(irWebsocketServer, '192.168.1.3', 8555))
loop.run_forever()

虽然将线程和asyncio混合并不完全是 * 错误 * 的,但正确地这样做需要注意不要混淆单独的asyncio示例。将线程用于asyncio的安全方法是使用loop.run_in_executor(),它在一个单独的线程中运行同步代码,而不会阻塞事件循环,同时从循环中返回一个对象await able。
注意:上面的代码是在asyncio.run()出现之前编写的,并且手动旋转事件循环。在Python 3.7和更高版本中,可能会这样写:

async def main():
    server1 = await websockets.serve(vlWebsocketServer, '192.168.1.3', 8777)
    server2 = await websockets.serve(irWebsocketServer, '192.168.1.3', 8555)
    await asyncio.gather(server1.wait_closed(), server2.wait_closed())

asyncio.run(main())

相关问题