comparison seobeo/docs/web_socket_client.md @ 120:cbbf78b17cfa

[Seobeo][Websocket] Created Web socket client logic.
author June Park <parkjune1995@gmail.com>
date Thu, 08 Jan 2026 03:19:59 -0800
parents
children
comparison
equal deleted inserted replaced
119:c39582f937e5 120:cbbf78b17cfa
1 # Seobeo WebSocket Client - Usage Guide
2
3 A clean, easy-to-use WebSocket client library following RFC 6455.
4
5 ## Features
6
7 1. **WebSocket Protocol Support**: Full RFC 6455 WebSocket implementation
8 2. **Text and Binary Messages**: Send/receive both text and binary data
9 3. **Automatic Ping/Pong**: Automatic pong responses to ping frames
10 4. **Message Fragmentation**: Handles fragmented messages automatically
11 5. **Secure WebSocket**: Supports both `ws://` and `wss://` (WebSocket over TLS)
12 6. **Clean API**: Simple, intuitive API following seobeo coding standards
13
14 ## API Overview
15
16 ### Core Functions
17
18 ```c
19 // Connect to WebSocket server
20 Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url);
21
22 // Send messages
23 int32 Seobeo_WebSocket_Send_Text(Seobeo_WebSocket *p_ws, const char *text);
24 int32 Seobeo_WebSocket_Send_Binary(Seobeo_WebSocket *p_ws, const uint8 *data, size_t length);
25
26 // Send control frames
27 int32 Seobeo_WebSocket_Send_Ping(Seobeo_WebSocket *p_ws, const char *payload);
28 int32 Seobeo_WebSocket_Send_Pong(Seobeo_WebSocket *p_ws, const char *payload);
29
30 // Receive messages
31 Seobeo_WebSocket_Message *Seobeo_WebSocket_Receive(Seobeo_WebSocket *p_ws);
32
33 // Close connection
34 int32 Seobeo_WebSocket_Close(Seobeo_WebSocket *p_ws, uint16 code, const char *reason);
35
36 // Clean up
37 void Seobeo_WebSocket_Message_Destroy(Seobeo_WebSocket_Message *p_msg);
38 void Seobeo_WebSocket_Destroy(Seobeo_WebSocket *p_ws);
39 ```
40
41 ### Message Opcodes
42
43 ```c
44 typedef enum {
45 SEOBEO_WS_OPCODE_CONTINUATION = 0x0, // Continuation frame
46 SEOBEO_WS_OPCODE_TEXT = 0x1, // Text message
47 SEOBEO_WS_OPCODE_BINARY = 0x2, // Binary message
48 SEOBEO_WS_OPCODE_CLOSE = 0x8, // Close connection
49 SEOBEO_WS_OPCODE_PING = 0x9, // Ping frame
50 SEOBEO_WS_OPCODE_PONG = 0xA // Pong frame
51 } Seobeo_WebSocket_Opcode;
52 ```
53
54 ### Connection States
55
56 ```c
57 typedef enum {
58 SEOBEO_WS_STATE_CONNECTING = 0, // Handshake in progress
59 SEOBEO_WS_STATE_OPEN, // Connection established
60 SEOBEO_WS_STATE_CLOSING, // Close handshake initiated
61 SEOBEO_WS_STATE_CLOSED // Connection closed
62 } Seobeo_WebSocket_State;
63 ```
64
65 ## Examples
66
67 ### 1. Simple Text Echo
68
69 ```c
70 // Connect to WebSocket server
71 Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://echo.websocket.org");
72 if (!p_ws)
73 {
74 printf("Failed to connect\n");
75 return;
76 }
77
78 // Send text message
79 const char *message = "Hello, WebSocket!";
80 Seobeo_WebSocket_Send_Text(p_ws, message);
81
82 // Receive echo response
83 Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
84 if (p_msg && p_msg->opcode == SEOBEO_WS_OPCODE_TEXT)
85 {
86 printf("Received: %.*s\n", (int)p_msg->length, (char*)p_msg->data);
87 Seobeo_WebSocket_Message_Destroy(p_msg);
88 }
89
90 // Close connection
91 Seobeo_WebSocket_Close(p_ws, 1000, "Normal closure");
92 Seobeo_WebSocket_Destroy(p_ws);
93 ```
94
95 ### 2. Binary Data Transfer
96
97 ```c
98 Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com/data");
99
100 // Send binary data
101 uint8 data[] = {0x01, 0x02, 0x03, 0xAA, 0xBB, 0xCC};
102 Seobeo_WebSocket_Send_Binary(p_ws, data, sizeof(data));
103
104 // Receive binary response
105 Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
106 if (p_msg && p_msg->opcode == SEOBEO_WS_OPCODE_BINARY)
107 {
108 printf("Received %zu bytes\n", p_msg->length);
109 // Process binary data...
110 Seobeo_WebSocket_Message_Destroy(p_msg);
111 }
112
113 Seobeo_WebSocket_Destroy(p_ws);
114 ```
115
116 ### 3. Chat Application
117
118 ```c
119 Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://chat.example.com");
120
121 // Send chat message
122 Seobeo_WebSocket_Send_Text(p_ws, "Hello everyone!");
123
124 // Continuous receive loop
125 while (1)
126 {
127 Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
128 if (p_msg)
129 {
130 if (p_msg->opcode == SEOBEO_WS_OPCODE_TEXT)
131 {
132 printf("Chat: %.*s\n", (int)p_msg->length, (char*)p_msg->data);
133 }
134 Seobeo_WebSocket_Message_Destroy(p_msg);
135 }
136
137 usleep(10000); // 10ms sleep to avoid busy waiting
138 }
139
140 Seobeo_WebSocket_Destroy(p_ws);
141 ```
142
143 ### 4. Ping/Pong Keep-Alive
144
145 ```c
146 Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://api.example.com");
147
148 // Send ping to keep connection alive
149 Seobeo_WebSocket_Send_Ping(p_ws, "keep-alive");
150
151 // Server will automatically receive pong responses
152 // (pong responses are handled internally)
153
154 Seobeo_WebSocket_Destroy(p_ws);
155 ```
156
157 ### 5. Handling Different Message Types
158
159 ```c
160 Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com");
161
162 while (1)
163 {
164 Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
165 if (p_msg)
166 {
167 switch (p_msg->opcode)
168 {
169 case SEOBEO_WS_OPCODE_TEXT:
170 printf("Text: %.*s\n", (int)p_msg->length, (char*)p_msg->data);
171 break;
172
173 case SEOBEO_WS_OPCODE_BINARY:
174 printf("Binary: %zu bytes\n", p_msg->length);
175 break;
176
177 default:
178 printf("Unknown opcode: 0x%X\n", p_msg->opcode);
179 break;
180 }
181
182 Seobeo_WebSocket_Message_Destroy(p_msg);
183 }
184
185 usleep(10000);
186 }
187
188 Seobeo_WebSocket_Destroy(p_ws);
189 ```
190
191 ### 6. Graceful Shutdown
192
193 ```c
194 Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com");
195
196 // Do work...
197
198 // Close with custom status code and reason
199 Seobeo_WebSocket_Close(p_ws, 1000, "Client shutting down");
200 Seobeo_WebSocket_Destroy(p_ws);
201 ```
202
203 ## WebSocket Close Codes
204
205 Common close status codes (RFC 6455):
206
207 - **1000**: Normal closure
208 - **1001**: Going away (e.g., server shutdown, browser navigation)
209 - **1002**: Protocol error
210 - **1003**: Unsupported data type
211 - **1006**: Abnormal closure (no close frame received)
212 - **1007**: Invalid frame payload data
213 - **1008**: Policy violation
214 - **1009**: Message too big
215 - **1010**: Mandatory extension missing
216 - **1011**: Internal server error
217
218 ## Building
219
220 ### Build the library:
221 ```bash
222 bazel build //seobeo:seobeo_client
223 ```
224
225 ### Build and run the WebSocket test:
226 ```bash
227 bazel test //seobeo:seobeo_websocket_test
228 ```
229
230 ## Message Structure
231
232 ```c
233 typedef struct {
234 Seobeo_WebSocket_Opcode opcode; // Message type
235 uint8 *data; // Message payload
236 size_t length; // Payload length
237 boolean is_final; // Final fragment flag
238 } Seobeo_WebSocket_Message;
239 ```
240
241 ## Protocol Details
242
243 The implementation follows RFC 6455:
244
245 1. **Handshake**: HTTP Upgrade request with `Sec-WebSocket-Key`
246 2. **Frame Format**: Proper FIN, opcode, mask, and payload length handling
247 3. **Masking**: All client-to-server frames are masked (required by RFC)
248 4. **Fragmentation**: Handles fragmented messages across multiple frames
249 5. **Control Frames**: Proper handling of ping, pong, and close frames
250 6. **TLS Support**: Supports secure WebSocket (wss://) via OpenSSL
251
252 ## Coding Standards
253
254 The implementation follows your specified coding standards:
255 - Naming: `Seobeo_WebSocket_Connect`, `Seobeo_WebSocket_Send_Text`
256 - Two spaces for indentation
257 - New line before `{` unless it's a struct
258 - Single statement: no need for `{}`
259
260 ## Features
261
262 ✅ WebSocket handshake (HTTP Upgrade)
263 ✅ Text and binary message support
264 ✅ Automatic masking for client frames
265 ✅ Message fragmentation handling
266 ✅ Ping/Pong frames
267 ✅ Close handshake
268 ✅ TLS/SSL support (wss://)
269 ✅ Non-blocking receive
270 ✅ Proper memory management with arenas