WebSocket Output Options Evaluation

This document captures the evaluation and comparison of approaches to add WebSocket output to mag-usb while keeping build and dependency constraints in mind.

Key constraint check

  • Both WebSocket++ and MengRao/websocket are C++ libraries; they require a C++ compiler and C++11+ (and typically Asio/Boost). That conflicts with “keep project C11” if you mean “no C++ toolchain required.”

  • “Header-only” does not mean “dependency-free.” WebSocket++ usually depends on Boost.Asio or standalone Asio, so you would still be vendoring additional headers and accepting C++ ABI/toolchain implications.

Option 1: Directly couple a WS library

  • Pros: single binary; lowest runtime plumbing; straightforward to broadcast data to multiple clients.

  • Cons: drags in C++ toolchain + Asio/Boost; changes build surface area; complicates CMake and portability; blurs C11 guarantee; harder to keep the core tiny.

  • Fit with constraints: poor.

Option 2: Directly couple behind a build flag

  • Pros: best of both worlds for users; core can still be “C-only” builds; optional feature for advanced setups.

  • Cons: still adds C++/Asio complexity for the optional path; dual build/test matrix; more maintenance.

  • Fit with constraints: acceptable only if you are willing to support a C++ toolchain in the optional build.

Option 3: Separate small WS bridge (websocketd-style)

  • Pros: preserves C11 core; no C++ dependency in mag-usb; simple piping (stdout/pipe); easiest to keep versioning isolated; can be swapped/replaced without touching core.

  • Cons: extra process; needs IPC (pipe/stdio); you must handle reconnection/backpressure in the bridge; packaging two binaries.

  • Fit with constraints: best match if “C11 core” is a hard requirement.

Library choice implications

  • WebSocket++: header-only but C++11+ and Asio/Boost; good maturity, but heavyweight for your goals.

  • MengRao/websocket: also C++-based; still violates C11-only goal.

  • Net: neither meets “C11-only” unless you accept a C++ optional component.

Alternative worth considering

  • A small C-based embedded server library (e.g., Mongoose) can be vendored as C source rather than a C++ dependency. That would allow Option 1 or 2 without a C++ toolchain, but introduces a third-party C library and licensing considerations.


Follow-up request and responses

User request: “I am willing to sacrifice the ‘C11 purity’ constraint, but I don’t want ASIO/Boost involved. I would like to pursue the option 2 using the meng/rao library. I want that library vendored into the project. This can all bive behind a build flag. I will need test cases and a test harness to explore the results.”

Assistant response: “Added optional WebSocket output behind -DENABLE_WEBSOCKET=ON, vendored MengRao/websocket under third_party/, and wired runtime config + CLI flags (-W, -w, -a) so mag-usb can broadcast each JSON line to connected WS clients. I also added a basic test (websocket-tests) and a small ws-client harness for manual exploration; docs and the requirements spec now reflect the new capability.

Details and touch points

  • Build flag and targets: CMakeLists.txt adds ENABLE_WEBSOCKET, ws-client, and websocket-tests

  • Runtime integration: src/main.c polls the WS server in the output loop and broadcasts the JSON line

  • Configuration + CLI: src/config.c, src/config.toml, src/cmdmgr.c, src/main.h

  • Wrapper and tooling: src/ws_bridge.h, src/ws_bridge.cpp, tools/ws_client.cpp, tests/test_websocket.cpp

  • Docs/reqs: docs/Configuration.md, docs/Getting-Started.md, docs/Requirements.md, README.md

  • third_party/mengrao-websocket/

Tests not run.

If you want to verify:

cmake -S . -B build -DENABLE_WEBSOCKET=ON
cmake --build build --target mag-usb ws-client
cmake --build build --target websocket-tests
(cd build && ctest --output-on-failure)

To try the harness:

./build/mag-usb -W -w 8765 -a 0.0.0.0
./build/ws-client 127.0.0.1 8765 /

If you want adjustments (port defaults, max connections, or a dedicated WS thread), tell me which behavior you prefer.”