【问题标题】:Python websocket context manager with a while True in body, closing connectionPython websocket上下文管理器,主体为真,关闭连接
【发布时间】:2021-07-26 09:09:38
【问题描述】:

从下一个测试代码开始

    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

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

【问题讨论】:

  • 请提供带有导入和正确缩进的完整工作代码,以便我们可以重现错误
  • 请同时提供完整的错误跟踪,以便清楚哪些行导致错误

标签: python websocket python-asyncio


【解决方案1】:

您可能正在关注websockets library example

如示例中所写:

在服务端,websockets执行handler协程hello 每个 WebSocket 连接一次。它关闭连接时 处理程序协程返回。

以下是示例中的 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 连接已关闭。

【讨论】:

  • 感谢您将问题指向服务器端,我只查看客户端认为问题存在,不断接收的解决方案在回调中使用 While True 循环就足够了。
猜你喜欢
  • 2018-03-09
  • 2015-10-01
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
相关资源
最近更新 更多