Skip to content

Channels

WebSocket connections in Nexios are managed using the Channel class, which provides enhanced functionality for handling real-time communication. Channels wrap WebSocket connections with additional features like metadata, expiration, and structured message handling.

Channel Features

  • Automatic Message Serialization: Supports JSON, text, and binary payloads
  • Connection Lifecycle Management: Built-in handling for connection states
  • Metadata Storage: Attach custom data to channels
  • Expiration: Automatic cleanup of inactive channels
  • Error Handling: Built-in error handling and cleanup

Creating and Using a Channel

Basic Channel Creation

python
from datetime import timedelta
from nexios.websockets.channels import Channel, PayloadTypeEnum
from nexios.websockets.base import WebSocketDisconnect

@app.websocket("/chat")
async def chat_handler(ws: WebSocket):
    # Accept the WebSocket connection
    await ws.accept()

    # Create a channel with JSON payload and 30-minute expiration
    channel = Channel(
        websocket=ws,
        payload_type=PayloadTypeEnum.JSON,  # Can be JSON, TEXT, or BINARY
        expires=1800,  # 30 minutes (optional)
        metadata={"username": "anonymous"}  # Optional metadata
    )

    try:
        while True:
            # Receive and process messages
            data = await channel.receive()  # Automatically deserializes based on payload_type

            # Send a response (automatically serializes based on payload_type)
            await channel.send({"response": data, "timestamp": datetime.utcnow().isoformat()})

            # Update channel metadata if needed
            if "username" in data:
                channel.metadata["username"] = data["username"]

    except WebSocketDisconnect:
        print(f"Client disconnected: {channel.id}")
    except Exception as e:
        print(f"Error in chat handler: {e}")
    finally:
        # Clean up resources
        await channel.close()

Channel Methods and Properties

python
# Get channel information
channel_id = channel.id  # UUID of the channel
is_active = channel.is_active  # Check if channel is still connected
created_at = channel.created  # When the channel was created
expires_at = channel.expires  # When the channel will expire

# Send different types of messages
await channel.send({"type": "message", "content": "Hello!"})  # JSON
await channel.send_text("Hello!")  # Plain text
await channel.send_bytes(b"binary_data")  # Binary data

# Receive messages (auto-deserialized based on payload_type)
data = await channel.receive()  # For JSON payloads
text = await channel.receive_text()  # For text payloads
binary = await channel.receive_bytes()  # For binary payloads

# Close the channel with an optional status code and reason
await channel.close(code=1000, reason="User left the chat")

Channel Expiration and Heartbeats

Channels can be configured to expire after a period of inactivity. To keep a channel alive, you can implement a heartbeat mechanism:

python
@app.websocket("/chat-with-heartbeat")
async def chat_handler(ws: WebSocket):
    await ws.accept()

    # Channel with 5-minute expiration
    channel = Channel(
        websocket=ws,
        payload_type=PayloadTypeEnum.JSON,
        expires=300  # 5 minutes
    )

    try:
        while True:
            data = await channel.receive()

            # Handle heartbeat messages
            if data.get("type") == "heartbeat":
                # Reset the expiration timer
                channel.touch()
                await channel.send({"type": "heartbeat_ack"})
                continue

            # Process other messages...

    except WebSocketDisconnect:
        print("Client disconnected")
    finally:
        await channel.close()

Best Practices for Channels

  1. Always Close Connections

    • Use try/finally blocks to ensure channels are properly closed
    • Handle WebSocketDisconnect exceptions gracefully
  2. Use Appropriate Payload Types

    • Use JSON for structured data
    • Use TEXT for simple string messages
    • Use BINARY for file transfers or raw binary data
  3. Implement Heartbeats

    • Keep long-lived connections alive with periodic heartbeats
    • Handle timeouts and reconnections on the client side
  4. Validate Input

    • Always validate and sanitize incoming messages
    • Use Pydantic models for message validation
  5. Monitor Channel Health

    • Track active channels and their status
    • Log connection events and errors
    • Implement rate limiting if needed