Python 3.5 Asyncio和多个websocket服务器

时间:2018-02-16 01:02:51

标签: python linux python-3.x websocket python-asyncio

我在Ubuntu上使用Python websockets 4.0.1。我想要运行2个websocket服务器。通过为每个线程创建2个线程和独立的事件循环,我能够将其变为“有点工作”。通过“工作”,我的意思是两个websockets都工作并且响应大约30秒,然后其中一个停止。我必须重新启动该过程才能使它们再次工作。如果我只运行这两个线程中的一个或另一个,那么单个websocket将永远运行。

我做错了什么,如何使用asyncio永远使用2个websockets?感谢。

# 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()

1 个答案:

答案 0 :(得分:2)

您不需要线程来运行多个asyncio任务 - 允许多个代理共享同一个事件循环是asyncio的强大功能。您应该能够使用以下代码替换这两个基于线程的类:

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

虽然混合线程和asyncio并不完全错误,但正确地这样做需要注意不要混淆单独的asyncio实例。使用线程进行asyncio的安全方法是loop.run_in_executor(),它在一个单独的线程中运行同步代码而不阻塞事件循环,同时从循环返回一个对象await