Python WebSocket发送给客户端并保持连接活动

时间:2018-11-16 03:46:07

标签: python websocket python-asyncio

我正在使用python websockets:https://websockets.readthedocs.io/

他们有一个简单的客户端/服务器示例,其中服务器将回显客户端的输入一次。代码如下:

客户端:

# WS client example

import asyncio
import websockets

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

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

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

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

服务器端:

# WS server example

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

我只想调整服务器端,以便在套接字连接时执行以下操作:

  1. 发送确认消息给客户端。例如Hello Client! Please wait for your data.
  2. 使连接保持活动状态。
  3. 处理一些需要一些时间的数据。
  4. 完成数据处理后,在现有的websocket连接上通知客户端。例如Your data is here!

python websockets文档没有执行此操作的代码示例。

2 个答案:

答案 0 :(得分:2)

要保持连接打开状态,请不要在处理第一条消息后终止处理程序。例如,您可以有一个无限循环,该循环将一直处理传入消息,直到客户端关闭连接为止。

async def hello(websocket, path):
    while True:
        try:
            name = await websocket.recv()
        except websockets.ConnectionClosed:
            print(f"Terminated")
            break

        print(f"< {name}")
        greeting = f"Hello {name}!"

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

然后在async的乐趣中,您可以await按照建议的here进行任何长时间运行的操作。

但是,您将需要以类似的方式调整服务器端和客户端。您的客户也将在收到第一条消息后终止。

答案 1 :(得分:1)

大概是您处理数据的函数正在阻塞,否则您只需将await放在协程内部即可。直接的方法是使用run_in_executor在另一个线程中运行它,并await在您的处理程序协程中运行:

async def hello(websocket, path):
    loop = asyncio.get_event_loop()
    await websocket.send("Hello Client! Please wait for your data.")
    data = await loop.run_in_executor(None, get_data)
    await websocket.send("Your data is here!")
    await websocket.send(data)

def get_data():
    # something that takes a long time to calculate
    x = 19134702400093278081449423917**300000 % 256
    return bytes([x])