I'm using 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:
Hello Client! Please wait for your data.
Your data is here!
The python websockets documentation doesn't have a code sample which does this.
Keepalive in websockets To avoid these problems, websockets runs a keepalive and heartbeat mechanism based on WebSocket Ping and Pong frames, which are designed for this purpose.
The key word in that definition is two-way: with WebSocket, both the client and the server can trigger communication with one another, and both can send messages, at the same time.
With WebSockets: the server can send a message to the client without the client explicitly requesting something. the client and the server can talk to each other simultaneously. very little data overhead needs to be exchanged to send messages.
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.
You will however need to adapt both server and client side in the similar way. Your client also terminates after receiving the first message.
Presumably your function that processes the data is blocking, otherwise you'd simply await
it inside the coroutine. The straightforward approach is to use run_in_executor
to run it in another thread, and await
it in your handler coroutine:
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])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With