feat(tcp): TCPStreamer DataSources, in-process TCPStreamService, stream multiplexing and TCPStreamJoin

Add TCPStreamer/TCPStreamerClient (TCP transport behind the UDPSServerI/UDPSClientI
seam), an optional single in-process TCPStreamService serving many streams over
worker threads, multiplexed SUBSCRIBE (comma list, stream index in fragmentIdx),
and TCPStreamJoin, which merges several streams into one sample-and-hold stream
paced by a master. StreamHub takes a comma list of streams over one connection.
Includes GTests, E2E scenarios s58-s73 and docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Opus 4.6 committed 2026-11-06 13:41:27 +01:00
1 parent 5562877c99
commit 50d85363a3
79 files changed
+12348 -138

No files matched your search

+2
View File
@@ -84,6 +84,8 @@ Two independent data paths:
1. **Streaming path**: `UDPStreamer` DataSource serialises signals each RT cycle to UDPS binary packets (UDP 44500, unicast/multicast) → `StreamHub` (`Source/Applications/StreamHub/`, headless C++ app: ring buffers, LTTB decimation, trigger FSM) → WebSocket 8090 → browser (`Client/udpstreamer`, Go), native ImGui client (`Client/streamhub`), or native Qt client (`Client/streamhub-qt`).
2. **Debug path**: `DebugService` patches the `ClassRegistryDatabase` at `Initialise()` so subsequent `ConfigureApplication()` instantiates `DebugBrokerWrapper<T>` around all `MemoryMap*Broker` types — no application changes. RT hot path goes through `DebugServiceI` (abstract singleton in `DebugServiceI.h`) for forcing/tracing/breakpoints. Exposes TCP 8080 (text commands), UDP 8081 (trace telemetry), works with `TcpLogger` on 8082. Web UI: `Client/debugger` (Go).
**TCP variant**: `TCPStreamer` / `TCPStreamerClient` (`Source/Components/DataSources/TCP*`) subclass `UDPStreamer` / `UDPStreamerClient` and swap the transport for `TCPSServer` / `TCPSClient` (`Source/Components/Interfaces/UDPStream/`) through the `UDPSServerI` / `UDPSClientI` seam in `UDPSTransportI.h`. Same UDPS framing (`totalFragments` always 1), per-client bounded queues so a slow client only drops its own frames. `TCPStreamService` (`Source/Components/Interfaces/TCPStreamService/`) is an optional single in-process server (acceptor + worker threads) shared by many `TCPStreamer`s via `Service=`/`StreamName=`; clients pick a stream with a SUBSCRIBE frame (UDPS type 5). A SUBSCRIBE may list several streams (`"a,b"`) to multiplex them over one socket (frames tagged with the stream index in `fragmentIdx`), and `TCPStreamJoin` publishes a merged stream (sample-and-hold of several streams paced by a master). StreamHub sources accept `Transport="tcp"` + `StreamName` (a comma list creates one session per stream). See `Docs/TCPStreamer.md`.
**Shared wire format**: `Common/UDP/UDPSProtocol.h` defines the UDPS binary protocol (17-byte packed header, 136-byte signal descriptors, little-endian). It is deliberately MARTe2-free so it's shared by C++ producers (`UDPStreamer`, `DebugService`), the C++ consumer (`Source/Components/Interfaces/UDPStream/UDPSClient`), the Go decoder (`Common/Client/go/udpsprotocol`), and the standalone C client (`Common/Client/c`, which redeclares the constants rather than including this header, so it stays MARTe-free). Changes to the protocol must be mirrored across all of these, plus the JS client parsers.
**StreamHub WebSocket protocol**: JSON text frames for commands/events, binary frames for data pushes — spec in `ARCHITECTURE.md` §6. The Go hub (`Client/udpstreamer`) and C++ StreamHub implement the identical protocol; both clients (browser JS and ImGui) must stay compatible with both.