Websockets

WebSocket is a communication protocol that provides a full-duplex, persistent communication channel over a single TCP connection. It is designed to be implemented in web browsers and web servers, but it can be used by any client or server application.

In simple terms, WebSockets allow for a two-way, interactive communication session between a user's browser and a server. This means the server can push messages to the client at any time, without the client having to request it.

Traditional web communication relies on the HTTP protocol, which follows a strict request-response model:

  1. The client sends an HTTP request to the server.
  2. The server processes the request and sends an HTTP response back.
  3. The connection is closed.

For applications requiring real-time data (like chat apps or live stock tickers), this model is inefficient. Developers had to use workarounds like polling, where the client repeatedly asks the server for new data, creating significant network overhead and latency.

Example

This example demonstrates a basic WebSocket server using FastAPI. It defines an endpoint that accepts incoming client connections, establishing a persistent channel to echo back any messages it receives.

Once deployed, the websocket session are recorded and visible on the UI

This script creates a simple web server using the FastAPI framework. It establishes a WebSocket endpoint that listens for incoming text messages, echoes them back to the sender with a prefix, and gracefully handles client disconnections.

1/4
2/4
3/4
4/4
from fastapi import FastAPI, WebSocket, WebSocketDisconnect

app = FastAPI()

# This function will handle the lifecycle of a client connection.
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    # This completes the WebSocket handshake.
    await websocket.accept()

    try:
        # The connection stays open until the client disconnects or an error occurs.
        while True:
            data = await websocket.receive_text()
            await websocket.send_text(f"Message text was: {data}")
    except WebSocketDisconnect:
        print("Client disconnected")

This script is a command-line WebSocket client that connects to a server and allows for real-time, two-way communication. It uses Python's asyncio library to concurrently listen for messages from the server and send user-typed messages, ensuring a non-blocking, interactive experience.

1/8
2/8
3/8
4/8
5/8
6/8
7/8
8/8
import asyncio
import websockets


# This function runs concurrently to receive and print messages from the server.
async def listener(websocket):
    """Listens for messages from the server and prints them."""
    try:
        async for message in websocket:
            print(f"\n<<< Received: {message}")
            print("Enter a message to send (or 'exit' to quit): ", end="", flush=True)
    except websockets.exceptions.ConnectionClosed:
        print("\nConnection to server closed.")
    except Exception as e:
        print(f"Listener error: {e}")


# This function runs concurrently to read user input and send it to the server.
async def sender(websocket):
    """Prompts the user for input and sends it to the server."""
    while True:
        try:
            message = await asyncio.to_thread(input, "")
            if message.lower() == "exit":
                print(">>> Closing connection...")
                break
            await websocket.send(message)
        except (KeyboardInterrupt, EOFError):
            print("\n>>> Closing connection...")
            break


async def main():
    """Main function to run the websocket client."""
    websocket_uri = "ws://127.0.0.1:8000/ws" # Using a standard local address

    try:
        async with websockets.connect(websocket_uri) as websocket:
            print("Successfully connected to the WebSocket server.")
            print("Enter a message to send (or 'exit' to quit): ", end="", flush=True)

            # This allows sending and receiving messages simultaneously.
            listener_task = asyncio.create_task(listener(websocket))
            sender_task = asyncio.create_task(sender(websocket))

            # If the user types 'exit' (sender) or the server connection closes (listener),
            # the program will proceed to shut down.
            done, pending = await asyncio.wait(
                [listener_task, sender_task],
                return_when=asyncio.FIRST_COMPLETED,
            )

            for task in pending:
                task.cancel()

    except websockets.exceptions.ConnectionClosedError:
        print(f"Error: Connection to {websocket_uri} failed. Is the server running?")
    except ConnectionRefusedError:
        print(f"Error: Connection refused. Please ensure the server is running on {websocket_uri}.")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
    finally:
        print("Client has disconnected.")

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nClient shut down by user.")

Was this page helpful?

What went wrong?

↑↓ Navigate↵ Open⌘↵ New tabesc Close