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

时间:2018-11-07 11:53:54

标签: python websocket python-asyncio

我为herewebsocket客户修改了一个示例,如下所示:

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 个答案:

答案 0 :(得分:1)

您更改了客户端,但没有更改服务器,因此问题出在服务器端。只需检查其代码即可。

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

接受新的连接后,它将等待来自客户端的第一条消息,然后将其发送回并退出处理程序。实际上,它只是关闭连接。因此,当您的客户端尝试发送第二条消息时,它失败并显示Connection closed错误。

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

  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}")

答案 1 :(得分:0)

只需检查此链接here,我就会遇到一个类似的问题,即长时间未打开该连接以使我能够实际执行所需的操作,因此我检查了此示例,没有抛出任何其他异常,您应该在代码中更改的主要内容应该是

  • 代替
async def hello(websocket, path):

使用

@async.coroutine
def hello (websocket,path)

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

  • 然后将其替换为like的收益
for m in ('msg1', 'msg2'):
            yield from websocket.send(m)
            print(f"> {m}")
            greeting = yield from websocket.recv()
            print(f"< {greeting}")

更多细节请参见我上面提到的github回购 哦,正如上面的评论所提到的,请不要忘记继续传递消息的无限循环