11#include <QSslConfiguration>
15#include <QWebSocketServer>
20#include <morph/core/remote.hpp>
21#include <morph/core/wire.hpp>
25#include <unordered_map>
158 std::optional<QSslConfiguration> tls = std::nullopt,
187 [[nodiscard]] quint16
port()
const;
239 QWebSocket* socket =
nullptr;
245 std::chrono::steady_clock::time_point lastRefill;
248 std::chrono::steady_clock::time_point lastActivity;
252 QTimer* handshakeTimer =
nullptr;
266 std::shared_ptr<std::atomic<std::size_t>> backlog = std::make_shared<std::atomic<std::size_t>>(0);
270 detail::OutboundLedger unwritten;
278 QPointer<QSslSocket> tls;
283 QTimer* sendTimer =
nullptr;
298 static bool queueEnvelope(QPointer<QtWebSocketServer>
const& server, QPointer<QWebSocket>
const& socket,
299 std::shared_ptr<std::atomic<std::size_t>>
const& backlog, std::string envelope);
306 void writeCounted(QWebSocket* socket, ClientState& state, std::string
const& envelope);
313 void writeNow(QWebSocket* socket, ClientState& state, std::string
const& envelope);
319 void releaseBacklog(ClientState
const& state, std::size_t bytes);
324 void armSendTimer(ClientState& state)
const;
329 void onSendTimer(QWebSocket* socket);
335 static qint64 pendingBytes(ClientState
const& state);
342 [[nodiscard]] QSslSocket* findTlsSocket(QWebSocket
const* socket)
const;
348 static void forgetConnection(ClientState& state);
355 bool consumeToken(ClientState& state)
const;
358 Q_SLOT
void onHousekeepingTick();
361 quint16 _requestedPort;
363 QWebSocketServer _wsServer;
364 std::unordered_map<QWebSocket*, ClientState> _clients;
365 QTimer _housekeepingTimer;
Server-side message handler that owns model instances and dispatches actions.
Q_SLOT void onBytesWritten(qint64 bytes)
Qt slot called when a client's socket has written bytes.
Q_SLOT void onDisconnected()
Qt slot called when a client disconnects.
Q_SLOT void onTextMessage(const QString &message)
Qt slot called when a connected client sends a text message.
bool closeGracefully(std::chrono::milliseconds deadline)
Gracefully stops the server: refuse new work, let in-flight replies deliver, close each client with a...
QtWebSocketServer(::morph::backend::RemoteServer &server, quint16 port=0, std::optional< QSslConfiguration > tls=std::nullopt, QtWebSocketServerConfig cfg=QtWebSocketServerConfig{}, QObject *parent=nullptr)
Constructs the server and prepares it to listen on port.
bool listen()
Starts listening for incoming WebSocket connections.
Q_SLOT void onNewConnection()
Qt slot called when a new client connects.
void close()
Stops accepting new connections and closes the server socket.
quint16 port() const
Returns the port the server is currently bound to.
~QtWebSocketServer() override
Closes the server and disconnects all clients.
QtWebSocketServerConfig Config
Alias for the per-connection limits configuration struct.
std::uint64_t ConnectionId
Opaque id a transport uses to scope model registrations to one connection so RemoteServer::closeConne...
Which frames handed to a socket it has written, told from the socket's own byte counts.
Per-connection resource limits and bind/exposure policy enforced by QtWebSocketServer.
std::chrono::milliseconds idleTimeout
Time a connection may go without sending any frame before it is closed. 0 = disabled.
std::chrono::milliseconds sendTimeout
Time a frame handed to a connection may stay unwritten before the connection is closed....
std::size_t maxMessageBytes
Per-frame size cap enforced before a message reaches RemoteServer::handle().
QHostAddress bindAddress
Address listen() binds to. Default QHostAddress::LocalHost.
std::size_t messagesPerSecond
Per-connection token-bucket rate limit, in messages per second. 0 = unbounded.
std::chrono::milliseconds handshakeTimeout
Time allowed for a newly-accepted connection to send its first text frame before it is closed....
bool allowPlaintextExposure
Deliberate opt-out of the exposure guard: set true only to knowingly serve plaintext (no TLS) on a no...
std::size_t maxConnections
Max simultaneous live client connections. 0 = unbounded.