Python
Understanding WebSockets: Real-Time Bi-Directional Communication in Python
Learn how WebSockets enable full-duplex communication between clients and servers. This guide explains the WebSocket handshake and demonstrates implementation using FastAPI and the websockets library.
June 2026 · 6 min read · 3 views · 0 hearts
Advertisement
Stop refreshing the page to see if your message sent—that's the 2005 way of doing things.
In the early days of the web, communication was a one-way street. Your browser (the client) asked a server for data, the server handed it over, and the connection closed. If you wanted new data, you had to ask again. This "request-response" cycle is the foundation of HTTP, but it’s fundamentally broken for things like live chat, stock tickers, or multiplayer games.
Enter WebSockets: the technology that turns the one-way street into a two-way highway.
What exactly are WebSockets?
A WebSocket is a persistent connection between a client and a server. Unlike HTTP, which opens and closes a connection for every single request, a WebSocket stays open. Once the initial "handshake" is complete, both the client and the server can send data to each other at any time without being asked.
This is known as full-duplex communication. Think of HTTP like sending a series of letters via mail; WebSockets are like a continuous phone call.
Why not just use "Polling"?
Before WebSockets, developers used "Long Polling." The browser would ask the server, "Is there any new data?" If the answer was "No," the server would hold the request open for a few seconds before replying. The browser would then immediately ask again.
This is incredibly inefficient. It creates massive overhead because every single request carries a heavy set of HTTP headers, wasting bandwidth and CPU cycles just to say "nothing has changed."
How the WebSocket Handshake Works
WebSockets actually start their life as an HTTP request. This ensures compatibility with existing web infrastructure (like firewalls and proxies).
- The Upgrade Request: The client sends a standard GET request to the server with a special header:
Upgrade: websocket. - The Switch: If the server supports WebSockets, it replies with an
HTTP 101 Switching Protocolsresponse. - The Tunnel: The HTTP connection is replaced by a WebSocket connection. From this point forward, the data transmitted is no longer in HTTP format; it uses a lightweight binary framing protocol.
Implementing WebSockets with Python
Python is an excellent choice for real-time servers. Because WebSockets are asynchronous by nature (you don't know when a message will arrive), you cannot use traditional synchronous frameworks like Django or Flask in their basic forms.
Instead, you need an Asynchronous Server Gateway Interface (ASGI).
Option 1: FastAPI (Modern & Fast)
FastAPI has native support for WebSockets and is one of the most popular choices today.
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Server received: {data}")
Option 2: websockets library (Low Level)
If you don't need a full web framework, the websockets library is the gold standard for building dedicated socket servers.
import asyncio
import websockets
async def echo(websocket):
async for message in websocket:
await websocket.send(f"Echo: {message}")
async def main():
async with websockets.serve(echo, "localhost", 8765):
await asyncio.Future() # run forever
asyncio.run(main())
The Challenges of Real-Time Communication
While WebSockets seem like a magic bullet, they introduce new complexities that HTTP doesn't have:
- State Management: Since the connection stays open, the server must remember who is connected. This consumes RAM. If you have 100,000 concurrent users, your server needs to maintain 100,000 open sockets.
- Scaling: You cannot easily load-balance WebSockets. If User A is connected to Server 1, and User B is connected to Server 2, Server 1 cannot simply "send" a message to User B. You need a Pub/Sub mechanism (like Redis) to synchronize messages across multiple server nodes.
- Connection Stability: Mobile phones switch from Wi-Fi to 4G constantly. WebSocket connections drop frequently, requiring robust "heartbeat" (ping/pong) logic to detect dead connections and trigger automatic reconnects.
When to use WebSockets vs. Other Options
WebSockets aren't always the right tool. Here is a quick cheat sheet:
| Technology | Direction | Best Use Case |
|---|---|---|
| HTTP REST | Client $\rightarrow$ Server | Blog posts, User profiles, CRUD apps |
| WebSockets | Bi-directional | Chat apps, Gaming, Collaborative editing (Google Docs) |
| Server-Sent Events (SSE) | Server $\rightarrow$ Client | Live news feeds, Stock tickers, Notifications |
SSE (Server-Sent Events) is a great middle-ground. It allows the server to push data to the client over HTTP, but the client cannot send data back through that same stream. If you only need a one-way live feed, SSE is simpler to implement and more stable than WebSockets.
Advertisement
Comments
Questions, corrections, and tips stay visible for everyone reading this page.
Join the discussion
No comments yet
Be the first to leave a note — it helps the next reader.