Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Real-Time WebSocket App

This recipe demonstrates setting up real-time bidirectional WebSocket communication with an interactive client interface.

Source code: examples/ws/


Server Implementation

const std = @import("std");
const http = @import("lighting");
const ws = http.extra.ws;

const index_html = @embedFile("index.html");

pub fn main(init: std.process.Init) !void {
    const allocator = init.gpa;
    const io = init.io;

    var mux = http.ServeMux.init(allocator);
    defer mux.deinit();

    // 1. Serve embedded interactive WebSocket HTML client
    try mux.handleFunc("GET /{$}", struct {
        fn handle(w: *http.ResponseWriter, _: *http.Request) anyerror!void {
            try w.header().set("Content-Type", "text/html; charset=utf-8");
            try w.writeAll(index_html);
        }
    }.handle);

    // 2. WebSocket upgrade and message echo loop
    try mux.handleFunc("GET /ws", struct {
        fn handle(w: *http.ResponseWriter, req: *http.Request) anyerror!void {
            var conn = ws.upgrade(w, req, .{}) catch |err| {
                std.log.warn("WebSocket upgrade error: {}", .{err});
                return;
            };
            defer conn.close();

            while (try conn.readMessage(req.arena)) |msg| {
                switch (msg.type) {
                    .text => {
                        var reply_buf: [512]u8 = undefined;
                        const reply = std.fmt.bufPrint(&reply_buf, "Echo: {s}", .{msg.payload}) catch msg.payload;
                        try conn.writeText(reply);
                    },
                    .binary => {
                        try conn.writeBinary(msg.payload);
                    },
                    .close => break,
                }
            }
        }
    }.handle);

    var server = http.Server.init(allocator, io, .{
        .handler = mux.handler(),
    });

    try server.listenAndServe("127.0.0.1", 7000);
}

Running the Example

make run-ws

Visit http://127.0.0.1:7000 to send text and binary messages and see the real-time responses.