Nyx by Example

Realtime Pub/Sub

Combine WebSocket with nyx-kv Pub/Sub to push real-time updates to browsers. Backend events PUBLISH to a channel; the web server SUBSCRIBEs and forwards as WebSocket frames to connected clients.

Code

// Real-time updates — WebSocket + nyx-kv Pub/Sub

import "std/websocket"

fn resp_cmd(parts: Array) -> String {
    var sb: StringBuilder = StringBuilder.new()
    sb.append("*" + int_to_string(parts.length()) + "\r\n")
    var i: int = 0
    while i < parts.length() {
        let p: String = parts[i]
        sb.append("$" + int_to_string(p.length()) + "\r\n" + p + "\r\n")
        i = i + 1
    }
    return sb.to_string()
}

// Publish an event to all subscribers
fn broadcast_event(channel: String, payload: String) -> int {
    let fd: int = tcp_connect("127.0.0.1", 6380)
    if fd < 0 { return -1 }
    tcp_write(fd, resp_cmd(["PUBLISH", channel, payload]))
    let reply: String = tcp_read_line(fd)
    print("broadcast to " + channel + ": " + reply.trim() + " subscribers")
    tcp_close(fd)
    return 0
}

// Forward nyx-kv messages to a WebSocket client
fn ws_stream_events(ws_fd: int, channel: String) -> int {
    let kv_fd: int = tcp_connect("127.0.0.1", 6380)
    if kv_fd < 0 { return -1 }

    // Subscribe to the channel
    tcp_write(kv_fd, resp_cmd(["SUBSCRIBE", channel]))

    // Read messages and forward as WebSocket frames
    // (simplified — real impl needs proper RESP parsing)
    let frame: String = ws_frame("{\"type\":\"connected\"}")
    tcp_write(ws_fd, frame)

    tcp_close(kv_fd)
    return 0
}

fn main() -> int {
    // Broadcast a user event — nyx-kv relays to all subscribers
    broadcast_event("user_events", "{\"type\":\"signup\",\"user\":\"alice\"}")
    broadcast_event("user_events", "{\"type\":\"login\",\"user\":\"alice\"}")

    print("real-time pattern:")
    print("  1. Web client connects via WebSocket")
    print("  2. Server SUBSCRIBEs to nyx-kv channel")
    print("  3. Backend PUBLISHes events to nyx-kv")
    print("  4. Server forwards messages as WS frames to client")
    return 0
}

Output

broadcast to user_events: 2 subscribers
broadcast to user_events: 2 subscribers
real-time pattern:
  1. Web client connects via WebSocket
  2. Server SUBSCRIBEs to nyx-kv channel
  3. Backend PUBLISHes events to nyx-kv
  4. Server forwards messages as WS frames to client

Explanation

Real-time browser updates need two half-duplex primitives glued together. WebSocket keeps the browser connection open; nyx-kv Pub/Sub fans out events across server workers. The browser talks only to its local web server, so it doesn't need to know nyx-kv exists — and nyx-kv handles fanout in C, so one PUBLISH reaches every subscriber in microseconds. This exact pattern powers live dashboards, chat, collaborative editors, and notification systems.

← Previous Next →

Source: examples/by-example/97-realtime-pubsub.nx