FastAPI WebSocket Chat Server

hardPython

Lesson

WebSocket Communication and Connection Management

WebSockets enable real-time, bidirectional communication between clients and servers, making them perfect for chat applications, live updates, and collaborative tools. Unlike traditional HTTP requests that follow a request-response pattern, WebSockets maintain persistent connections that allow both client and server to send messages at any time.

The key challenge in WebSocket applications is connection management - tracking active connections, organizing them into groups (like chat rooms), and handling disconnections gracefully. When building multi-room chat systems, you need to maintain data structures that map rooms to their active connections, broadcast messages only to relevant users, and clean up resources when users leave.

Broadcasting is the core pattern for real-time communication. When one user sends a message, the server must deliver it to all other users in the same room. This requires iterating through stored connections and sending the message to each WebSocket. Error handling is crucial here - if a connection has been closed unexpectedly, attempting to send will fail and you need to remove that connection from your tracking system.

Connection lifecycle management involves three phases: joining (accepting the connection and adding to room), active communication (receiving and broadcasting messages), and leaving (cleaning up on disconnect). The disconnect phase is particularly important because it can happen suddenly when users close browsers or lose network connectivity.

FastAPI's WebSocket support makes this straightforward with await websocket.accept() for connections, await websocket.receive_text() for incoming messages, and await websocket.send_text() for outgoing messages. The WebSocketDisconnect exception handles cleanup when connections end unexpectedly.

Example
1from fastapi import FastAPI, WebSocket, WebSocketDisconnect 2from typing import Dict, List 3 4app = FastAPI() 5connections: Dict[str, List[WebSocket]] = {} 6 7@app.websocket("/ws/{room}") 8async def websocket_endpoint(websocket: WebSocket, room: str): 9 await websocket.accept() 10 11 # Add to room 12 if room not in connections: 13 connections[room] = [] 14 connections[room].append(websocket) 15 16 try: 17 while True: 18 message = await websocket.receive_text() 19 # Broadcast to all in room 20 for ws in connections[room]: 21 await ws.send_text(f"Room {room}: {message}") 22 except WebSocketDisconnect: 23 # Clean up on disconnect 24 connections[room].remove(websocket) 25 if not connections[room]: 26 del connections[room]
L9Accept the WebSocket connection to establish the persistent channel
L16Receive_text() blocks until a message arrives from the client
L20WebSocketDisconnect exception handles unexpected connection closures

Key Takeaways

  • •WebSockets maintain persistent connections for real-time bidirectional communication
  • •Connection management requires tracking active connections and cleaning up on disconnect
  • •Broadcasting involves sending messages to multiple WebSocket connections in a group
Loading...