Implemented new C++ logic

This commit is contained in:
Martino Ferrari
2026-06-12 15:25:13 +02:00
parent 617b5bd712
commit f25bd7f08e
220 changed files with 39185 additions and 850 deletions
+132
View File
@@ -0,0 +1,132 @@
/**
* @file WSServer.h
* @brief Multi-client WebSocket server using MARTe2 BasicTCPSocket.
*
* Accepts WebSocket connections over HTTP/1.1 (RFC 6455 upgrade).
* - One accept thread (started by Start()).
* - One read thread per connected client (started when client upgrades).
* - BroadcastText / BroadcastBinary called from any thread (push loop or
* command handlers); per-client write is protected by a mutex.
*
* Maximum concurrent clients: WS_MAX_CLIENTS (16).
*/
#ifndef STREAMHUB_WSSERVER_H_
#define STREAMHUB_WSSERVER_H_
#include "BasicTCPSocket.h"
#include "FastPollingMutexSem.h"
namespace StreamHub {
using MARTe::uint8;
using MARTe::uint16;
using MARTe::uint32;
using MARTe::BasicTCPSocket;
using MARTe::FastPollingMutexSem;
/** Maximum simultaneously connected WebSocket clients. */
static const uint32 WS_MAX_CLIENTS = 16u;
/** Maximum WebSocket frame payload we will receive (commands are JSON, small). */
static const uint32 WS_MAX_RECV_PAYLOAD = 65536u;
/** Maximum WebSocket frame payload we will send (data frames can be large). */
static const uint32 WS_MAX_SEND_PAYLOAD = 4u * 1024u * 1024u; /* 4 MiB */
/**
* @brief Callback interface — implemented by StreamHub.
*/
class WSCommandCallback {
public:
virtual ~WSCommandCallback() {}
/** Called from client read thread with a fully-received text frame.
* @param slotIdx Client slot index — usable with WSServer::SendText for
* unicast replies. */
virtual void OnWSCommand(const char *json, uint32 len, uint32 slotIdx) = 0;
/** Called from accept thread when a new client upgrades. */
virtual void OnWSClientConnected() = 0;
/** Called from client read thread when the connection closes. */
virtual void OnWSClientDisconnected() = 0;
};
/**
* @brief One connected WebSocket client slot.
*/
struct WSClientSlot {
BasicTCPSocket *sock; ///< Owned pointer; NULL when slot is free
bool active;
MARTe::ThreadIdentifier readTid;
FastPollingMutexSem writeMutex; ///< Serialises writes from push + pong threads
};
/**
* @brief Minimal HTTP/1.1 + WebSocket server.
*/
class WSServer {
public:
WSServer();
~WSServer();
/**
* @brief Open listen socket and start the accept thread.
* @param port TCP port to listen on.
* @param cb Command callback (StreamHub); must outlive WSServer.
* @return true on success.
*/
bool Start(uint16 port, WSCommandCallback *cb);
/**
* @brief Stop accept thread; close all client connections; close listener.
*/
bool Stop();
/**
* @brief Broadcast a text (JSON) frame to all connected clients.
* Safe to call from any thread.
*/
void BroadcastText(const char *json, uint32 len);
/**
* @brief Broadcast a binary frame to all connected clients.
* Safe to call from any thread.
*/
void BroadcastBinary(const uint8 *buf, uint32 len);
/**
* @brief Send a text frame to a single client slot.
* Used internally to send pong / direct responses.
*/
void SendText(uint32 slotIdx, const char *json, uint32 len);
/** @return Number of currently active client connections. */
uint32 ClientCount() const;
/* ---- Internal thread entry points (public for Threads trampoline) ---- */
void AcceptLoop();
void ClientReadLoop(uint32 slotIdx);
private:
bool UpgradeHTTP(BasicTCPSocket *sock);
bool SendFrame(WSClientSlot &slot, uint8 opcode,
const uint8 *payload, uint32 payloadLen);
uint32 AllocSlot(BasicTCPSocket *sock);
void FreeSlot(uint32 idx);
BasicTCPSocket tcpListener;
WSClientSlot clients[WS_MAX_CLIENTS];
uint32 numClients;
mutable FastPollingMutexSem clientsMutex; ///< Protects numClients and clients[] array
WSCommandCallback *callback;
volatile bool running;
MARTe::ThreadIdentifier acceptTid;
};
} /* namespace StreamHub */
#endif /* STREAMHUB_WSSERVER_H_ */