Mercurial
view seobeo/docs/web_socket_client.md @ 211:a6d8d32a0261
[MrJuneJune] Simple animations for darkmode.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sun, 15 Feb 2026 21:38:23 -0800 |
| parents | cbbf78b17cfa |
| children |
line wrap: on
line source
# Seobeo WebSocket Client - Usage Guide A clean, easy-to-use WebSocket client library following RFC 6455. ## Features 1. **WebSocket Protocol Support**: Full RFC 6455 WebSocket implementation 2. **Text and Binary Messages**: Send/receive both text and binary data 3. **Automatic Ping/Pong**: Automatic pong responses to ping frames 4. **Message Fragmentation**: Handles fragmented messages automatically 5. **Secure WebSocket**: Supports both `ws://` and `wss://` (WebSocket over TLS) 6. **Clean API**: Simple, intuitive API following seobeo coding standards ## API Overview ### Core Functions ```c // Connect to WebSocket server Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url); // Send messages int32 Seobeo_WebSocket_Send_Text(Seobeo_WebSocket *p_ws, const char *text); int32 Seobeo_WebSocket_Send_Binary(Seobeo_WebSocket *p_ws, const uint8 *data, size_t length); // Send control frames int32 Seobeo_WebSocket_Send_Ping(Seobeo_WebSocket *p_ws, const char *payload); int32 Seobeo_WebSocket_Send_Pong(Seobeo_WebSocket *p_ws, const char *payload); // Receive messages Seobeo_WebSocket_Message *Seobeo_WebSocket_Receive(Seobeo_WebSocket *p_ws); // Close connection int32 Seobeo_WebSocket_Close(Seobeo_WebSocket *p_ws, uint16 code, const char *reason); // Clean up void Seobeo_WebSocket_Message_Destroy(Seobeo_WebSocket_Message *p_msg); void Seobeo_WebSocket_Destroy(Seobeo_WebSocket *p_ws); ``` ### Message Opcodes ```c typedef enum { SEOBEO_WS_OPCODE_CONTINUATION = 0x0, // Continuation frame SEOBEO_WS_OPCODE_TEXT = 0x1, // Text message SEOBEO_WS_OPCODE_BINARY = 0x2, // Binary message SEOBEO_WS_OPCODE_CLOSE = 0x8, // Close connection SEOBEO_WS_OPCODE_PING = 0x9, // Ping frame SEOBEO_WS_OPCODE_PONG = 0xA // Pong frame } Seobeo_WebSocket_Opcode; ``` ### Connection States ```c typedef enum { SEOBEO_WS_STATE_CONNECTING = 0, // Handshake in progress SEOBEO_WS_STATE_OPEN, // Connection established SEOBEO_WS_STATE_CLOSING, // Close handshake initiated SEOBEO_WS_STATE_CLOSED // Connection closed } Seobeo_WebSocket_State; ``` ## Examples ### 1. Simple Text Echo ```c // Connect to WebSocket server Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://echo.websocket.org"); if (!p_ws) { printf("Failed to connect\n"); return; } // Send text message const char *message = "Hello, WebSocket!"; Seobeo_WebSocket_Send_Text(p_ws, message); // Receive echo response Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws); if (p_msg && p_msg->opcode == SEOBEO_WS_OPCODE_TEXT) { printf("Received: %.*s\n", (int)p_msg->length, (char*)p_msg->data); Seobeo_WebSocket_Message_Destroy(p_msg); } // Close connection Seobeo_WebSocket_Close(p_ws, 1000, "Normal closure"); Seobeo_WebSocket_Destroy(p_ws); ``` ### 2. Binary Data Transfer ```c Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com/data"); // Send binary data uint8 data[] = {0x01, 0x02, 0x03, 0xAA, 0xBB, 0xCC}; Seobeo_WebSocket_Send_Binary(p_ws, data, sizeof(data)); // Receive binary response Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws); if (p_msg && p_msg->opcode == SEOBEO_WS_OPCODE_BINARY) { printf("Received %zu bytes\n", p_msg->length); // Process binary data... Seobeo_WebSocket_Message_Destroy(p_msg); } Seobeo_WebSocket_Destroy(p_ws); ``` ### 3. Chat Application ```c Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://chat.example.com"); // Send chat message Seobeo_WebSocket_Send_Text(p_ws, "Hello everyone!"); // Continuous receive loop while (1) { Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws); if (p_msg) { if (p_msg->opcode == SEOBEO_WS_OPCODE_TEXT) { printf("Chat: %.*s\n", (int)p_msg->length, (char*)p_msg->data); } Seobeo_WebSocket_Message_Destroy(p_msg); } usleep(10000); // 10ms sleep to avoid busy waiting } Seobeo_WebSocket_Destroy(p_ws); ``` ### 4. Ping/Pong Keep-Alive ```c Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://api.example.com"); // Send ping to keep connection alive Seobeo_WebSocket_Send_Ping(p_ws, "keep-alive"); // Server will automatically receive pong responses // (pong responses are handled internally) Seobeo_WebSocket_Destroy(p_ws); ``` ### 5. Handling Different Message Types ```c Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com"); while (1) { Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws); if (p_msg) { switch (p_msg->opcode) { case SEOBEO_WS_OPCODE_TEXT: printf("Text: %.*s\n", (int)p_msg->length, (char*)p_msg->data); break; case SEOBEO_WS_OPCODE_BINARY: printf("Binary: %zu bytes\n", p_msg->length); break; default: printf("Unknown opcode: 0x%X\n", p_msg->opcode); break; } Seobeo_WebSocket_Message_Destroy(p_msg); } usleep(10000); } Seobeo_WebSocket_Destroy(p_ws); ``` ### 6. Graceful Shutdown ```c Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com"); // Do work... // Close with custom status code and reason Seobeo_WebSocket_Close(p_ws, 1000, "Client shutting down"); Seobeo_WebSocket_Destroy(p_ws); ``` ## WebSocket Close Codes Common close status codes (RFC 6455): - **1000**: Normal closure - **1001**: Going away (e.g., server shutdown, browser navigation) - **1002**: Protocol error - **1003**: Unsupported data type - **1006**: Abnormal closure (no close frame received) - **1007**: Invalid frame payload data - **1008**: Policy violation - **1009**: Message too big - **1010**: Mandatory extension missing - **1011**: Internal server error ## Building ### Build the library: ```bash bazel build //seobeo:seobeo_client ``` ### Build and run the WebSocket test: ```bash bazel test //seobeo:seobeo_websocket_test ``` ## Message Structure ```c typedef struct { Seobeo_WebSocket_Opcode opcode; // Message type uint8 *data; // Message payload size_t length; // Payload length boolean is_final; // Final fragment flag } Seobeo_WebSocket_Message; ``` ## Protocol Details The implementation follows RFC 6455: 1. **Handshake**: HTTP Upgrade request with `Sec-WebSocket-Key` 2. **Frame Format**: Proper FIN, opcode, mask, and payload length handling 3. **Masking**: All client-to-server frames are masked (required by RFC) 4. **Fragmentation**: Handles fragmented messages across multiple frames 5. **Control Frames**: Proper handling of ping, pong, and close frames 6. **TLS Support**: Supports secure WebSocket (wss://) via OpenSSL ## Coding Standards The implementation follows your specified coding standards: - Naming: `Seobeo_WebSocket_Connect`, `Seobeo_WebSocket_Send_Text` - Two spaces for indentation - New line before `{` unless it's a struct - Single statement: no need for `{}` ## Features ✅ WebSocket handshake (HTTP Upgrade) ✅ Text and binary message support ✅ Automatic masking for client frames ✅ Message fragmentation handling ✅ Ping/Pong frames ✅ Close handshake ✅ TLS/SSL support (wss://) ✅ Non-blocking receive ✅ Proper memory management with arenas