简体   繁体   English

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

[英]Python websockets send to client and keep connection alive

I'm using python websockets: https://websockets.readthedocs.io/ 我正在使用python websockets: https ://websockets.readthedocs.io/

They have a simple client/server example, where the server echoes the client's input back once. 他们有一个简单的客户端/服务器示例,其中服务器将回显客户端的输入一次。 The code looks like this: 代码如下:

Client side: 客户端:

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

Server side: 服务器端:

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

I want to adapt just the server side only, so that it does the following upon a socket connection: 我只想调整服务器端,以便在套接字连接上执行以下操作:

  1. Send an acknowledgement message to the client. 发送确认消息给客户端。 eg Hello Client! Please wait for your data. 例如, Hello Client! Please wait for your data. Hello Client! Please wait for your data.
  2. Keep the connection alive. 使连接保持活动状态。
  3. Process some data that takes some time. 处理一些需要一些时间的数据。
  4. After the data has completed processing, notify the client on the existing websocket connection. 数据完成处理后,在现有的websocket连接上通知客户端。 eg Your data is here! 例如, Your data is here!

The python websockets documentation doesn't have a code sample which does this. python websockets文档没有执行此操作的代码示例。

Presumably your function that processes the data is blocking, otherwise you'd simply await it inside the coroutine. 大概您处理数据的函数正在阻塞,否则您只需在协程内部await它。 The straightforward approach is to use run_in_executor to run it in another thread, and await it in your handler coroutine: 直接的方法是使用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])

To keep the connection open do not terminate the handler after processing the first message. 要保持连接打开,请不要在处理第一条消息后终止处理程序。 For example, you can have an endless-loop that will keep processing the incoming messages until the connection is closed by the client: 例如,您可以拥有一个无限循环,该循环将一直处理传入消息,直到客户端关闭连接为止:

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

In the async fun you can then await any long running operation as suggested here . 然后,您可以在async乐趣中await 此处建议的任何长时间运行的操作。

You will however need to adapt both server and client side in the similar way. 但是,您将需要以类似的方式调整服务器端和客户端。 Your client also terminates after receiving the first message. 您的客户端在收到第一条消息后也会终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM