如何在Python Web框架Quart中实现WebSocket客户端的注册与注销?
Handling WebSocket Client Registration/Unregistration in Quart
Got it, let's refine your approach to fit Quart's WebSocket system perfectly. The example you found is close, but Quart uses a slightly different handler structure, and we can make this more robust.
First, a quick callout: using a set instead of a list is smarter here—sets automatically handle duplicate connections, and adding/removing entries is faster than with lists.
Here's a complete, working implementation:
from quart import Quart, websocket import asyncio app = Quart(__name__) # Store connected clients in a set attached to the app instance (cleaner than globals) app.connected_clients = set() @app.websocket('/ws') async def ws_handler(): # Register the new client: get the actual WebSocket object (Quart uses a proxy) current_ws = websocket._get_current_object() app.connected_clients.add(current_ws) try: # Example: Broadcast a "new client joined" update to everyone await asyncio.gather(*[ client.send(f"New client connected! Total: {len(app.connected_clients)}") for client in app.connected_clients ]) # Keep the connection alive and handle incoming messages while True: incoming_msg = await websocket.receive() # Example: Broadcast the received message to all connected clients await asyncio.gather(*[ client.send(f"Someone said: {incoming_msg}") for client in app.connected_clients ]) finally: # Unregister the client no matter why the connection closes (error, timeout, etc.) app.connected_clients.remove(current_ws) # Broadcast a "client left" update if app.connected_clients: # Only send if there are remaining clients await asyncio.gather(*[ client.send(f"Client disconnected! Total: {len(app.connected_clients)}") for client in app.connected_clients ]) if __name__ == '__main__': app.run(debug=True)
Key Details to Understand:
app.connected_clientsover global variables: Tying the client set to the app instance keeps your state organized and avoids issues if you ever run multiple app instances.websocket._get_current_object(): Quart uses a proxy for thewebsocketvariable in handlers, so we need the actual underlying object to store in the set (proxies aren't hashable).try/finallyblock: This guarantees the client is removed from the set every time the connection closes—whether the client disconnects normally, the network drops, or an error crashes the handler.asyncio.gather(): This is the cleanest way to run multiple send operations concurrently in async code, ensuring all clients get messages without blocking each other.
Testing This Setup:
You can test with a quick JavaScript client in your browser's console:
const ws = new WebSocket('ws://localhost:5000/ws'); ws.onmessage = (event) => console.log(event.data); ws.send('Hello from the browser!'); // Test disconnection later with: ws.close();
This setup will reliably track all connected clients, add them on connection, and remove them the moment they disconnect.
内容的提问来源于stack exchange,提问作者Dup Dup




