Python websockets 发送到客户端并保持连接活动

Ant*_*ton 7 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())
Run Code Online (Sandbox Code Playgroud)

服务器端:

# 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()
Run Code Online (Sandbox Code Playgroud)

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

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

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

Pet*_*ard 8

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

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}")
Run Code Online (Sandbox Code Playgroud)

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

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

  • 您能告诉我如何为客户端编写相同的“hello”函数吗? (2认同)

use*_*342 6

大概你处理数据的函数是阻塞的,否则你只是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])
Run Code Online (Sandbox Code Playgroud)