websockets¶
Uses the websockets.asyncio server from
websockets 13 and later.
import asyncio
from websockets.asyncio.server import ServerConnection, serve
from jsonrpcserver import Result, Success, async_dispatch, method
@method
async def ping() -> Result:
return Success("pong")
async def handler(websocket: ServerConnection) -> None:
async for message in websocket:
request = message.decode() if isinstance(message, bytes) else message
# Unlike HTTP, there's no need to answer a notification.
# max_batch_size: see the Security page.
if response := await async_dispatch(request, max_batch_size=100):
await websocket.send(response)
async def main() -> None:
# A bigger message closes the connection. The default is 1 MiB.
async with serve(handler, "localhost", 8000, max_size=1_000_000) as server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
Unlike HTTP, a WebSocket doesn't need an answer to every message, so a
notification gets nothing back. websockets closes the connection if a message
is bigger than max_size. Its default is 1 MiB (1,048,576 bytes). The
example sets 1,000,000, like the other examples. max_batch_size limits how many requests one batch can hold. See
Security.
Requests on one connection are handled one at a time, in the order they arrive. To answer them concurrently, start a task for each message.
Try it¶
Save the example as websockets_server.py, install websockets
(pip install websockets), and run it:
python websockets_server.py
websockets comes with an interactive client. Run
python -m websockets ws://localhost:8000/ in another terminal and type a
request, such as {"jsonrpc": "2.0", "method": "ping", "id": 1}.
From Python, jsonrpcclient's websockets example calls this server.