WebSockets

Xyra provides first-class support for WebSockets, allowing real-time, bidirectional communication between clients and the server.

Event-Based Handlers

You can handle WebSocket connections by providing a dictionary of event handlers to the app.websocket() method. This approach is excellent for organizing complex logic.

Python
from xyra import App, WebSocket

app = App()

async def on_open(ws: WebSocket):
    print("Client connected.")
    ws.subscribe("chat_room")
    await ws.send("Welcome to the chat!")

async def on_message(ws: WebSocket, message: str, opcode: int):
    print(f"Received: {message}")
    # Broadcast the message to all clients in the "chat_room"
    app.publish("chat_room", f"New message: {message}")

async def on_close(ws: WebSocket, code: int, message: str | None):
    print("Client disconnected.")

app.websocket("/ws/chat", {
    "open": on_open,
    "message": on_message,
    "close": on_close,
})

Key WebSocket Methods

The WebSocket object provides several methods for interaction:

  • await ws.send(data: str | bytes): Sends a text or binary message.
  • await ws.receive(): Asynchronously waits for and receives a message.
  • ws.close(code: int, message: str): Closes the connection.
  • ws.subscribe(topic: str): Subscribes the connection to a pub/sub topic.
  • app.publish(topic: str, message: str | bytes): Publishes a message from the app to all clients subscribed to a topic.
  • ws.unsubscribe(topic: str): Unsubscribes the connection from a topic.

Client-Side Example

Here is a simple HTML and JavaScript example for connecting to a WebSocket server.

HTML
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Client</title>
</head>
<body>
    <h1>WebSocket Test</h1>
    <input type="text" id="messageInput" placeholder="Enter a message" />
    <button onclick="sendMessage()">Send</button>
    <div id="messages" style="margin-top: 20px;"></div>

    <script>
        const ws = new WebSocket("ws://localhost:8000/ws/chat");
        const messagesDiv = document.getElementById('messages');
        const input = document.getElementById('messageInput');

        ws.onopen = () => console.log("WebSocket connected.");
        ws.onclose = () => console.log("WebSocket disconnected.");

        ws.onmessage = (event) => {
            const messageEl = document.createElement('p');
            messageEl.textContent = `Server: ${event.data}`;
            messagesDiv.appendChild(messageEl);
        };

        function sendMessage() {
            if (input.value) {
                ws.send(input.value);
                input.value = '';
            }
        }
    </script>
</body>
</html>