ESC
Type to search...
S
Soli Docs

WebSockets

Build real-time, interactive experiences. Soli provides native WebSocket support for chat apps, notifications, and live updates.

Want to see it in action?

Check out the interactive WebSocket chat demo included in this app.

Try Live Demo

Defining a Route

Register WebSocket endpoints in config/routes.soli.

config/routes.soli
// Map path to handler function
router_websocket("/ws/chat", "websocket#chat_handler");

Handling Events

Handlers receive connection events and return actions.

app/controllers/websocket_controller.soli
fn chat_handler(event: Any) -> Any {
    let type = event["type"];
    let id = event["connection_id"];

    if (type == "connect") {
        return { "broadcast": json_encode({ "type": "join", "user": id }) };
    }

    if (type == "message") {
        let msg = event["message"];
        return { "broadcast": msg };
    }

    return {};
}

The Event Object

type

Event kind: "connect", "message", or "disconnect".

connection_id

Unique UUID string identifying the client connection.

message

The text payload sent by the client (only for "message").

Response Actions

Broadcast

Send a message to ALL connected clients (including sender).

{"broadcast": "Hello All"}

Send (Reply)

Send a message ONLY to the client who triggered the event.

{"send": "Hello You"}

Client-Side Code

JavaScript
// Connect to WebSocket
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = new WebSocket(`${protocol}//${location.host}/ws/chat`);

ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('Received:', data);
};

ws.send(JSON.stringify({ text: 'Hello!' }));

Performance

10k+
Messages / Sec
<1ms
Latency
Async
Non-blocking I/O

Optimization Tip

Use send instead of broadcast whenever possible. Broadcasting to thousands of clients is significantly more expensive than a direct reply.