如何使用异步Websockets客户端保持连接活动?

3
我修改了一个我在这里找到的websocket客户端示例,如下所示:
import asyncio
import websockets
async def hello(messages):
    async with websockets.connect('ws://localhost:8765') as websocket:
        for m in ('msg1', 'msg2'):
            await websocket.send(m)
            print(f"> {m}")
            greeting = await websocket.recv()
            print(f"< {greeting}")
asyncio.get_event_loop().run_until_complete(hello(['name1', 'name2']))

但是现在,只要第二个send()被执行,就会出现异常:

Traceback (most recent call last):
  File "ws-client.py", line 44, in <module>
    main()
  File "ws-client.py", line 41, in main
    asyncio.get_event_loop().run_until_complete(hello(['name1', 'name2']))
  File "/usr/lib64/python3.6/asyncio/base_events.py", line 468, in run_until_complete
    return future.result()
  File "ws-client.py", line 35, in hello
    greeting = await websocket.recv()
  File "/home/frans/.local/lib/python3.6/site-packages/websockets/protocol.py", line 350, in recv
    yield from self.ensure_open()
  File "/home/frans/.local/lib/python3.6/site-packages/websockets/protocol.py", line 512, in ensure_open
    self.close_code, self.close_reason) from self.transfer_data_exc
websockets.exceptions.ConnectionClosed: WebSocket connection is closed: code = 1000 (OK), no reason

我对asyncio不是很了解 - 请问有人能告诉我哪里有问题吗?

我也使用了示例中的服务器代码...

2个回答

3

你更换了客户端,但没有更改服务器,所以问题出现在服务器端。请检查其代码。

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

在接受新连接后,服务器等待客户端的第一条消息,然后将其回送并退出处理程序。实际上,它只是关闭了连接。因此,当您的客户端尝试发送第二条消息时,会出现“连接已关闭”错误。

您可以像这样更改服务器,将处理程序有效载荷重复两次。

  async def hello(websocket, path):
      for _ in range(2):  # or while True if you need an infinite echo server
          name = await websocket.recv()
          print(f"< {name}")

          greeting = f"Hello {name}!"

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

0

请查看此链接here。我遇到了类似的问题,连接没有保持打开时间足够长,以便我实际上想要做的事情,所以我检查了这个示例,不再抛出任何异常,您应该在代码中更改的主要内容应该是

  • 而不是
async def hello(websocket, path):

使用

@async.coroutine
def hello (websocket,path)

因此,该函数将有资格成为协程生成器

  • 然后用yield from替换await,如下所示
for m in ('msg1', 'msg2'):
            yield from websocket.send(m)
            print(f"> {m}")
            greeting = yield from websocket.recv()
            print(f"< {greeting}")

更多细节请参见我上面提到的 Github 存储库,还有如上评论所提到的,别忘了无限循环以实现持续消息传递。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接