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:
1 parent
5562877c99
commit
50d85363a3
79 files changed
+12348
-138
No files matched your search
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* @file TCPStreamer.h
|
||||
* @brief Header file for class TCPStreamer
|
||||
* @date 05/11/2026
|
||||
* @author Martino Ferrari
|
||||
*
|
||||
* @copyright Copyright 2015 F4E | European Joint Undertaking for ITER and
|
||||
* the Development of Fusion Energy ('Fusion for Energy').
|
||||
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved
|
||||
* by the European Commission - subsequent versions of the EUPL (the "Licence")
|
||||
* You may not use this work except in compliance with the Licence.
|
||||
* You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
|
||||
*
|
||||
* @warning Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the Licence is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the Licence permissions and limitations under the Licence.
|
||||
*
|
||||
* @details This header file contains the declaration of the class TCPStreamer
|
||||
* with all of its public, protected and private members.
|
||||
*/
|
||||
|
||||
#ifndef TCPSTREAMER_H_
|
||||
#define TCPSTREAMER_H_
|
||||
|
||||
#include "TCPSServer.h"
|
||||
#include "TCPSServiceStream.h"
|
||||
#include "UDPStreamer.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
/**
|
||||
* @brief A DataSource that streams MARTe2 signals to TCP clients.
|
||||
*
|
||||
* @details Identical to UDPStreamer (same signals, quantisation, time modes and
|
||||
* PublishingMode handling, same UDPS wire format) except that the network side
|
||||
* is a TCPSServer: every client gets the CONFIG on connect and then every DATA
|
||||
* frame, in order, over its own TCP connection. A client that cannot keep up
|
||||
* only loses its own frames (counted by GetClientDrops()) and is disconnected
|
||||
* after ClientStallTimeout seconds without progress; the RT thread and the
|
||||
* other clients are unaffected.
|
||||
*
|
||||
* @par Configuration
|
||||
* All UDPStreamer keys apply except the UDP-only ones (MulticastGroup,
|
||||
* Interface, DataPort, ClientTimeout), which are rejected.
|
||||
* | Parameter | Type | Default | Description |
|
||||
* |--------------------|--------|---------|-------------|
|
||||
* | Port | uint16 | 44500 | TCP listen port. |
|
||||
* | MaxPayloadSize | uint32 | 60000 | Frame budget used to size Accumulate batches. |
|
||||
* | MaxClients | uint32 | 16 | Simultaneous clients (1..1024). |
|
||||
* | ClientQueueDepth | uint32 | 8 | DATA frames queued per client (1..4096). |
|
||||
* | ClientStallTimeout | uint32 | 5 | Seconds without progress before a client is dropped; 0 disables. |
|
||||
* | SendBufferSize | uint32 | 0 | SO_SNDBUF for client sockets; 0 keeps the OS default. |
|
||||
*
|
||||
* @par Shared service mode
|
||||
* With `Service = <name of a TCPStreamService>` the DataSource does not open a
|
||||
* socket of its own: it publishes a stream called `StreamName` (default: the
|
||||
* DataSource name) through the shared in-process service, which serves many
|
||||
* streams from one port with a pool of worker threads. Clients select the
|
||||
* stream with the `StreamName` key of TCPStreamerClient / StreamHub. In this
|
||||
* mode Port, MaxClients, ClientQueueDepth, ClientStallTimeout and
|
||||
* SendBufferSize belong to the service and are rejected here.
|
||||
* | Parameter | Type | Default | Description |
|
||||
* |------------|--------|-----------------|-------------|
|
||||
* | Service | string | *(absent)* | Object name of the TCPStreamService. |
|
||||
* | StreamName | string | DataSource name | Stream name, unique per service (1..255 chars). |
|
||||
*
|
||||
* @par Example
|
||||
* <pre>
|
||||
* +Streamer = {
|
||||
* Class = TCPStreamer
|
||||
* Port = 44500
|
||||
* Signals = {
|
||||
* Time = { Type = uint64 }
|
||||
* Value = { Type = float32 }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
class TCPStreamer : public UDPStreamer {
|
||||
public:
|
||||
CLASS_REGISTER_DECLARATION()
|
||||
|
||||
TCPStreamer();
|
||||
virtual ~TCPStreamer();
|
||||
|
||||
/** Rejects the UDP-only keys, then behaves as UDPStreamer::Initialise(). */
|
||||
virtual bool Initialise(StructuredDataI &data);
|
||||
|
||||
/** @return true when publishing through a TCPStreamService. */
|
||||
bool UsesService() const;
|
||||
/** @return the port actually bound (meaningful once started; resolves Port = 0). */
|
||||
uint16 GetBoundPort() const;
|
||||
/** @return clients currently connected. */
|
||||
uint32 GetClientCount() const;
|
||||
/** @return DATA frames dropped across all clients because their queue was full. */
|
||||
uint64 GetClientDrops() const;
|
||||
/** @return clients disconnected for exceeding ClientStallTimeout. */
|
||||
uint32 GetStallEvictions() const;
|
||||
|
||||
protected:
|
||||
virtual uint32 DefaultMaxPayloadSize() const;
|
||||
virtual bool InitialiseTransport(StructuredDataI &data);
|
||||
|
||||
private:
|
||||
TCPSServer *tcpServer; /**< Alias of the private transport (NULL in service mode). */
|
||||
TCPSServiceStream *serviceStream; /**< Alias of the service handle (NULL in standalone mode). */
|
||||
};
|
||||
|
||||
} /* namespace MARTe */
|
||||
|
||||
#endif /* TCPSTREAMER_H_ */
|
||||
Reference in new issue
Block a user