WebSocket Implementation
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The WebSocket implementation in HXLibs provides a full-duplex communication protocol over a single TCP connection, integrated with the library's asynchronous C++20 coroutine framework. It supports both server-side connection acceptance and client-side connection establishment, adhering to the RFC 6455 standard. The system handles the initial HTTP upgrade handshake, frame masking for clients, and efficient packet management for high-performance messaging.
Sources: include/HXLibs/net/protocol/websocket/WebSocket.hpp:31-40, include/HXLibs/net/protocol/websocket/WebSocket.hpp:674-686
Architecture and Core Components
The WebSocket implementation relies on three primary components: the WebSocket class, the WebSocketFactory, and the underlying IOType (typically HttpIO or HttpsIO). The system uses a template-based approach to differentiate between Client and Server models at compile time.
Key Data Structures
| Structure | Description |
|---|---|
WebSocketPacket | Represents a single WebSocket frame containing an OpCode and string content. |
WebSocketServerSendView | An optimized structure for server broadcasts, containing pre-built headers and content views. |
OpCode | Enum defining frame types: Text (1), Binary (2), Close (8), Ping (9), and Pong (10). |
WebSocketModel | Enum used to toggle client (masking enabled) or server (masking disabled) behavior. |
Sources: include/HXLibs/net/protocol/websocket/WebSocket.hpp:104-142, include/HXLibs/net/protocol/websocket/WebSocket.hpp:674-682
Connection Lifecycle
The connection begins with an HTTP GET request containing Upgrade: websocket and Connection: Upgrade headers. The server validates the Sec-WebSocket-Key using a SHA-1 hash and Base64 encoding before returning a 101 Switching Protocols status.
The diagram shows the handshake and subsequent full-duplex data exchange.
Sources: include/HXLibs/net/protocol/websocket/WebSocket.hpp:513-575, include/HXLibs/net/protocol/websocket/WebSocket.hpp:590-625
Server-Side Implementation
The server uses WebSocketFactory::accept() to upgrade an existing HttpRequest. It verifies mandatory headers like Origin and Upgrade. Once established, the server can use sendText, sendBytes, or sendJson to communicate with the client.
Frame Processing
When receiving data, the server parses the 2-byte header to determine the FIN bit and OpCode. It then reads the payload length (supporting 7-bit, 16-bit, and 64-bit lengths) and applies the 4-byte Masking-key provided by the client to decrypt the payload.
Sources: include/HXLibs/net/protocol/websocket/WebSocket.hpp:325-452
Messaging and Broadcasting
For high-performance scenarios, the server supports a WSPool pattern. The sendPacketView function allows the server to build a frame header once and send it to multiple clients along with the content view, minimizing memory allocation and copying.
This flow illustrates the optimized broadcast mechanism for servers.
Sources: tests/server/02_ws_server.cpp:55-68, include/HXLibs/net/protocol/websocket/WebSocket.hpp:674-722
Client-Side Implementation
Clients initiate connections via HttpClient::wsLoop or WebSocketFactory::connect. The client version of the WebSocket class includes a random number generator (XorShift32) to produce mandatory masking keys for every outgoing frame.
Handshake and Masking
- The client generates a random 16-byte Base64 string for the
Sec-WebSocket-Key. - For every data packet, the client generates a new 4-byte
mask. - The client XORs each byte of the payload with the masking key before transmission.
Sources: include/HXLibs/net/protocol/websocket/WebSocket.hpp:78-95, include/HXLibs/net/protocol/websocket/WebSocket.hpp:169-173, include/HXLibs/net/protocol/websocket/WebSocket.hpp:490-505
Automated Management
The HttpClient provides a wsLoop method that manages the event loop for WebSocket connections. It supports automatic reconnection if the _isAutoReconnect flag is set, ensuring robust communication despite transient network failures.
Sources: include/HXLibs/net/client/HttpClient.hpp:424-486, tests/client/03_brokenWireAndReconnected.cpp:89-100
Control Frames and Heartbeats
The implementation automatically handles Ping/Pong frames to maintain connection health.
- Ping/Pong: If a read operation times out, the implementation sends a
Ping. If the subsequentPongalso times out, it throws aruntime_error. - Close: The
close()method initiates a handshake by sending aCloseframe and waiting for a reciprocalCloseframe from the peer. - Fragmentation: The system supports fragmented data frames (where
FINis 0) but prohibits fragmented control frames as per RFC specifications.
Sources: include/HXLibs/net/protocol/websocket/WebSocket.hpp:228-258, include/HXLibs/net/protocol/websocket/WebSocket.hpp:302-317, include/HXLibs/net/protocol/websocket/WebSocket.hpp:370-385
Summary
The HXLibs WebSocket implementation provides a C++20 coroutine-based interface for bidirectional messaging. By utilizing WebSocketFactory for handshakes and template-specialized classes for client/server roles, it ensures high-performance data transfer with minimal overhead. The system includes built-in support for JSON serialization, automated heartbeat management, and optimized broadcasting for server-side connection pools.
Sources: include/HXLibs/net/protocol/websocket/WebSocket.hpp:212-225, tests/net/net_server.cpp:202-224