6 · WebSockets

Los WebSockets son rutas, registradas igual que los handlers HTTP. app_ws(pattern, handler) usa el mismo matcher {param} — así que una sala de chat es solo un parámetro.

Una sala de eco

import "std/websocket"

fn ws_room_handler(info: Array) -> int {
    let fd: int = info[0]
    let headers: Array = info[2]
    let params: Array = info[3]   // plano [k1, v1, k2, v2, ...]

    var room: String = "?"
    var i: int = 0
    while i + 1 < params.length() {
        let k: String = params[i]
        if k == "room" {
            let v: String = params[i + 1]
            room = v
        }
        i = i + 2
    }

    let key: String = http_find_header(headers, "Sec-WebSocket-Key")
    tcp_write(fd, ws_handshake_response(key))

    let data: String = tcp_read_partial(fd, 4096)
    if data.length() > 0 and !ws_is_close(data) {
        let msg: String = ws_parse(data)
        tcp_write(fd, ws_frame("[" + room + "] " + msg))
    }
    tcp_write(fd, ws_close())
    tcp_close(fd)
    return 1   // el fd es nuestro — el servidor no lo toca
}

fn main() {
    let app: App = app_new()
    app_ws("/ws/chat/{room}", ws_room_handler)
    serve_app(app, 3000, 8)
}

El contrato del handler:

Pruébalo

Conéctate con cualquier cliente WebSocket a ws://localhost:3000/ws/chat/general y envía un mensaje — recibes de vuelta [general] tu mensaje. El parámetro {room} prueba que ruteó.

Este handler sirve un mensaje y cierra — el ejemplo completo más chico. Un chat real mantiene el loop abierto y, para hacer broadcast entre conexiones, comparte estado por Pub/Sub de nyx-kv. Leer y escribir frames parciales está todo en std/websocket.