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.
Recommended direction¶
If C11 purity is non-negotiable: choose Option 3 and build a minimal WS bridge (could be in C++ if you are fine with that in the separate tool, or in C if you want everything C-only). This keeps mag-usb simple and stable while still enabling WS.
If you can tolerate optional C++: choose Option 2 with a build flag and keep WS in a separate module. Users who do not want C++ just build without it.
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.txtaddsENABLE_WEBSOCKET,ws-client, andwebsocket-testsRuntime integration:
src/main.cpolls the WS server in the output loop and broadcasts the JSON lineConfiguration + CLI:
src/config.c,src/config.toml,src/cmdmgr.c,src/main.hWrapper and tooling:
src/ws_bridge.h,src/ws_bridge.cpp,tools/ws_client.cpp,tests/test_websocket.cppDocs/reqs:
docs/Configuration.md,docs/Getting-Started.md,docs/Requirements.md,README.mdthird_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.”