如何通过 websocket 使用多线程?

Kha*_*lil 4 python multithreading websocket

我正在尝试使用多线程的 websocket ( https://websockets.readthedocs.io/en/stable/ )。我想要的是在程序继续运行时继续获取数据,但是,当我像下面的代码那样执行操作时,服务器没有收到来自客户端的任何连接。我之前在主线程上运行过它并且运行良好。

async def hello(websocket, path):
    while True:
        data = await websocket.recv()
        print(data)
        await websocket.send(data)


def between_callback():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    ws_server = websockets.serve(hello, '192.168.0.115', 8899)
    
    loop.run_until_complete(ws_server)
    loop.close()

if __name__ == "__main__":
    _thread = threading.Thread(target=between_callback)
    _thread.start()

  # Do something in main thread
Run Code Online (Sandbox Code Playgroud)

Boo*_*boo 8

查看websockets示例程序,您似乎缺少一条语句,loop.run_forever()这似乎确实有所不同(我还将 IP 地址更改为“localhost”进行测试):


def between_callback():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    ws_server = websockets.serve(hello, 'localhost', 8899)

    loop.run_until_complete(ws_server)
    loop.run_forever() # this is missing
    loop.close()
Run Code Online (Sandbox Code Playgroud)

演示程序

请注意,更新后的hello函数避免了websockets.exceptions.ConnectionClosedOK: code = 1000 (OK),终止时无原因异常,我怀疑这是由于守护线程的终止而引起的。

import websockets
import threading
import asyncio

async def hello(websocket, path):
    async for data in websocket:
        print(f"Received: '{data}'")
        await websocket.send(data)

def between_callback():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    ws_server = websockets.serve(hello, 'localhost', 8899)

    loop.run_until_complete(ws_server)
    loop.run_forever() # this is missing
    loop.close()

async def send_receive_message(uri):
    async with websockets.connect(uri) as websocket:
        await websocket.send('This is some text.')
        reply = await websocket.recv()
        print(f"The reply is: '{reply}'")

def client():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(send_receive_message('ws://localhost:8899'))
    loop.close()

if __name__ == "__main__":
    # daemon server thread:
    server = threading.Thread(target=between_callback, daemon=True)
    server.start()
    client = threading.Thread(target=client)
    client.start()
    client.join()
Run Code Online (Sandbox Code Playgroud)

印刷:

Received: 'This is some text.'
The reply is: 'This is some text.'
Run Code Online (Sandbox Code Playgroud)