Python websocket context manager with while True in body, closing connection

Python websocket context manager with a while True in body, closing connection

来自下一个测试代码

    async def hello():
    uri = "ws://localhost:8765"

    while True:
        async with websockets.connect(uri) as ws:
            await ws.send("Test \n")
            await asyncio.sleep(1)


if __name__ == "__main__":
    asyncio.run(hello())

此代码执行每秒发送一条消息的预期行为, 但似乎通过进行如下所示的更改可以提高效率:

    async def hello():
    uri = "ws://localhost:8765"

    
    async with websockets.connect(uri) as ws:
        while True:
            await ws.send("Test \n")
            await asyncio.sleep(1)


if __name__ == "__main__":
    asyncio.run(hello())

但是,在第二种方法中,上下文管理器退出并输出下一个异常:

    raise self.connection_closed_exc()
    websockets.exceptions.ConnectionClosedOK: code = 1000 (OK), no reason

如果正文在上下文管理器中正确缩进,为什么上下文管理器会关闭连接?

您可能正在关注 websockets 图书馆 example

如示例中所写:

On the server side, websockets executes the handler coroutine hello once for each WebSocket connection. It closes the connection when the handler coroutine returns.

下面是示例中的 Websockets 服务器:

import asyncio
import websockets

async def hello(websocket, path):
    name = await websocket.recv()
    print(f"< {name}")

    greeting = f"Hello {name}!"

    await websocket.send(greeting)
    print(f"> {greeting}")

start_server = websockets.serve(hello, "localhost", 8765)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

并且 Websockets 客户端修改为使用 while True 循环:

import asyncio
import websockets

async def hello():
    uri = "ws://localhost:8765"
    async with websockets.connect(uri) as websocket:
        name = input("What's your name? ")

        while True:
            print(websocket.closed)
            await websocket.send("Test")
            await asyncio.sleep(1)

        print(f"> {name}")

        greeting = await websocket.recv()
        print(f"< {greeting}")


asyncio.get_event_loop().run_until_complete(hello())

运行 服务器然后客户端提供以下输出:

在服务器中:

< Test
> Hello Test!

在客户端:

What's your name? hi
False
True
...
websockets.exceptions.ConnectionClosedOK: code = 1000 (OK), no reason

在您介绍的第一个案例中,代码会在每次循环迭代时创建 websocket 连接。而在第二个中,代码重用了在处理后由服务器关闭的连接,如文档所述。您可以通过检查 websocket.closed 字段看到 websocket 连接已关闭。