Minimal WebSocket echo server written in strict C23 with a libuv transport layer and built with Zig. Protocol handling is separated from the event loop via a small transport interface and exposed to the application through on_open, on_message, and on_close callbacks.
- HTTP Upgrade handshake with Sec-WebSocket-Key SHA1 + Base64 response and required header validation.
- Frame parsing with client masking enforcement, control frames (ping/pong/close), and text/binary payload delivery.
- Server replies are framed (FIN set, unmasked) for text/binary/close/pong responses.
- Echo behavior: logs text/binary messages and echoes payloads; a text message of
pingreceives apongreply.
- Fragmented data frames are not supported; continuation frames are closed with a protocol error.
- Payloads are capped at 1 MiB to avoid unbounded buffering; control frames are limited to 125 bytes.
- No TLS, authentication, permessage-deflate, or extensions; connections are plain TCP.
- Suitable as a starting point for experimenting with libuv and C23 patterns, not for production use.
- Zig (for the build system) and a C toolchain that supports
-std=c23. - libuv headers and libraries (e.g.,
sudo apt install libuv1-devorbrew install libuv). - Optional tools:
justfor task shortcuts,clang-formatfor formatting,valgrindfor leak checks, andwscat/k6for quick client tests.
- Default debug build:
just buildorzig build. - Release-style builds:
zig build -Doptimize=ReleaseSafe(orReleaseFast/ReleaseSmall). - Address/UB/leak sanitizers (Debug only):
zig build -Dsanitizers=true.
- Start the server on the default port 8080:
just runorzig build run. - Choose a port:
zig build run -- 9090orjust run p=9090. - Shutdown signals: SIGINT/SIGTERM trigger a graceful loop stop.
- The server logs connections, message receipt, and close events to stdout.
- Connect with a WebSocket client:
wscat -c ws://localhost:8080. - Send
pingto receivepong, or send any text/binary payload to see it echoed. - A basic k6 script is available at
ws_test.jsfor light load checks.
src/main.c— wires CLI args, signal handling, and application callbacks.src/server.c— libuv server setup, connection lifecycle, and transport glue.src/websocket.c/include/websocket-server/websocket.h— protocol handling, framing, and callbacks.build.zig— Zig build graph, compiler flags (-std=c23 -Wall -Wextra -Wpedantic -Werror), and sanitizer toggles.justfile— helper tasks for build, run, deps, format, and leak checks.