Implemented new C++ logic
This commit is contained in:
@@ -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_ */
|
||||
Reference in New Issue
Block a user