comparison seobeo/seobeo.h @ 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 c39582f937e5
children 7b1719fa918c
comparison
equal deleted inserted replaced
119:c39582f937e5 120:cbbf78b17cfa
86 extern Seobeo_Client_Response *Seobeo_Client_Request_Execute(Seobeo_Client_Request *p_req); 86 extern Seobeo_Client_Response *Seobeo_Client_Request_Execute(Seobeo_Client_Request *p_req);
87 /* Destroy request and free all resources. */ 87 /* Destroy request and free all resources. */
88 extern void Seobeo_Client_Request_Destroy(Seobeo_Client_Request *p_req); 88 extern void Seobeo_Client_Request_Destroy(Seobeo_Client_Request *p_req);
89 /* Destroy response and free all resources. */ 89 /* Destroy response and free all resources. */
90 extern void Seobeo_Client_Response_Destroy(Seobeo_Client_Response *p_resp); 90 extern void Seobeo_Client_Response_Destroy(Seobeo_Client_Response *p_resp);
91
92 /**
93 * WebSocket Client API
94 * ------
95 *
96 * # Overview
97 *
98 * A clean, easy-to-use WebSocket client library following RFC 6455. It will auto handle over 64 bits long data into a continous stream.
99 *
100 * ## Examples
101 *
102 * ### 1. Simple Text Echo
103 *
104 * ```c
105 * // Connect to WebSocket server
106 * Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://echo.websocket.org");
107 * if (!p_ws)
108 * {
109 * printf("Failed to connect\n");
110 * return;
111 * }
112 *
113 * // Send text message
114 * const char *message = "Hello, WebSocket!";
115 * Seobeo_WebSocket_Send_Text(p_ws, message);
116 *
117 * // Receive echo response
118 * Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
119 * if (p_msg && p_msg->opcode == SEOBEO_WS_OPCODE_TEXT)
120 * {
121 * printf("Received: %.*s\n", (int)p_msg->length, (char*)p_msg->data);
122 * Seobeo_WebSocket_Message_Destroy(p_msg);
123 * }
124 *
125 * // Close connection
126 * Seobeo_WebSocket_Close(p_ws, 1000, "Normal closure");
127 * Seobeo_WebSocket_Destroy(p_ws);
128 * ```
129 *
130 * ### 2. Binary Data Transfer
131 *
132 * ```c
133 * Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com/data");
134 *
135 * // Send binary data
136 * uint8 data[] = {0x01, 0x02, 0x03, 0xAA, 0xBB, 0xCC};
137 * Seobeo_WebSocket_Send_Binary(p_ws, data, sizeof(data));
138 *
139 * // Receive binary response
140 * Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
141 * if (p_msg && p_msg->opcode == SEOBEO_WS_OPCODE_BINARY)
142 * {
143 * printf("Received %zu bytes\n", p_msg->length);
144 * // Process binary data...
145 * Seobeo_WebSocket_Message_Destroy(p_msg);
146 * }
147 *
148 * Seobeo_WebSocket_Destroy(p_ws);
149 * ```
150 *
151 * ### 3. Chat Application
152 *
153 * ```c
154 * Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://chat.example.com");
155 *
156 * // Send chat message
157 * Seobeo_WebSocket_Send_Text(p_ws, "Hello everyone!");
158 *
159 * // Continuous receive loop
160 * while (1)
161 * {
162 * Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
163 * if (p_msg)
164 * {
165 * if (p_msg->opcode == SEOBEO_WS_OPCODE_TEXT)
166 * {
167 * printf("Chat: %.*s\n", (int)p_msg->length, (char*)p_msg->data);
168 * }
169 * Seobeo_WebSocket_Message_Destroy(p_msg);
170 * }
171 *
172 * usleep(10000); // 10ms sleep to avoid busy waiting
173 * }
174 *
175 * Seobeo_WebSocket_Destroy(p_ws);
176 * ```
177 *
178 * ### 4. Ping/Pong Keep-Alive
179 *
180 * ```c
181 * Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://api.example.com");
182 *
183 * // Send ping to keep connection alive
184 * Seobeo_WebSocket_Send_Ping(p_ws, "keep-alive");
185 *
186 * // Server will automatically receive pong responses
187 * // (pong responses are handled internally)
188 *
189 * Seobeo_WebSocket_Destroy(p_ws);
190 * ```
191 *
192 * ### 5. Handling Different Message Types
193 *
194 * ```c
195 * Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com");
196 *
197 * while (1)
198 * {
199 * Seobeo_WebSocket_Message *p_msg = Seobeo_WebSocket_Receive(p_ws);
200 * if (p_msg)
201 * {
202 * switch (p_msg->opcode)
203 * {
204 * case SEOBEO_WS_OPCODE_TEXT:
205 * printf("Text: %.*s\n", (int)p_msg->length, (char*)p_msg->data);
206 * break;
207 *
208 * case SEOBEO_WS_OPCODE_BINARY:
209 * printf("Binary: %zu bytes\n", p_msg->length);
210 * break;
211 *
212 * default:
213 * printf("Unknown opcode: 0x%X\n", p_msg->opcode);
214 * break;
215 * }
216 *
217 * Seobeo_WebSocket_Message_Destroy(p_msg);
218 * }
219 *
220 * usleep(10000);
221 * }
222 *
223 * Seobeo_WebSocket_Destroy(p_ws);
224 * ```
225 *
226 * ### 6. Graceful Shutdown
227 *
228 * ```c
229 * Seobeo_WebSocket *p_ws = Seobeo_WebSocket_Connect("wss://example.com");
230 *
231 * // Do work...
232 *
233 * // Close with custom status code and reason
234 * Seobeo_WebSocket_Close(p_ws, 1000, "Client shutting down");
235 * Seobeo_WebSocket_Destroy(p_ws);
236 * ```
237 *
238 * ## WebSocket Close Codes
239 *
240 * Common close status codes (RFC 6455):
241 *
242 * - **1000**: Normal closure
243 * - **1001**: Going away (e.g., server shutdown, browser navigation)
244 * - **1002**: Protocol error
245 * - **1003**: Unsupported data type
246 * - **1006**: Abnormal closure (no close frame received)
247 * - **1007**: Invalid frame payload data
248 * - **1008**: Policy violation
249 * - **1009**: Message too big
250 * - **1010**: Mandatory extension missing
251 * - **1011**: Internal server error
252 *
253 * ## Building
254 *
255 * ### Build the library:
256 * ```bash
257 * bazel build //seobeo:seobeo_client
258 * ```
259 *
260 * ### Build and run the WebSocket test:
261 * ```bash
262 * bazel test //seobeo:seobeo_websocket_test
263 * ```
264 *
265 * ## Message Structure
266 *
267 * ```c
268 * typedef struct {
269 * Seobeo_WebSocket_Opcode opcode; // Message type
270 * uint8 *data; // Message payload
271 * size_t length; // Payload length
272 * boolean is_final; // Final fragment flag
273 * } Seobeo_WebSocket_Message;
274 * ```
275 *
276 * ## Protocol Details
277 *
278 * The implementation follows RFC 6455
279 *
280 * 1. **Handshake**: HTTP Upgrade request with `Sec-WebSocket-Key`
281 * 2. **Frame Format**: Proper FIN, opcode, mask, and payload length handling
282 * 3. **Masking**: All client-to-server frames are masked (required by RFC)
283 * 4. **Fragmentation**: Handles fragmented messages across multiple frames
284 * 5. **Control Frames**: Proper handling of ping, pong, and close frames
285 */
286
287 /* Connect to WebSocket server with given URL (ws:// or wss://). */
288 extern Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url);
289 /* Send text message over WebSocket. */
290 extern int32 Seobeo_WebSocket_Send_Text(Seobeo_WebSocket *p_ws, const char *text);
291 /* Send binary message over WebSocket. */
292 extern int32 Seobeo_WebSocket_Send_Binary(Seobeo_WebSocket *p_ws, const uint8 *data, size_t length);
293 /* Send ping frame (for keep-alive). */
294 extern int32 Seobeo_WebSocket_Send_Ping(Seobeo_WebSocket *p_ws, const char *payload);
295 /* Send pong frame (usually in response to ping). */
296 extern int32 Seobeo_WebSocket_Send_Pong(Seobeo_WebSocket *p_ws, const char *payload);
297 /* Receive a message from WebSocket. Returns NULL if no message available or on error. */
298 extern Seobeo_WebSocket_Message *Seobeo_WebSocket_Receive(Seobeo_WebSocket *p_ws);
299 /* Destroy received message. */
300 extern void Seobeo_WebSocket_Message_Destroy(Seobeo_WebSocket_Message *p_msg);
301 /* Close WebSocket connection with status code and optional reason. */
302 extern int32 Seobeo_WebSocket_Close(Seobeo_WebSocket *p_ws, uint16 code, const char *reason);
303 /* Destroy WebSocket and free all resources. */
304 extern void Seobeo_WebSocket_Destroy(Seobeo_WebSocket *p_ws);
305
91 /* Initialize the router system (called automatically by Seobeo_Web_Server_Start) */ 306 /* Initialize the router system (called automatically by Seobeo_Web_Server_Start) */
92 extern void Seobeo_Router_Init(); 307 extern void Seobeo_Router_Init();
93 /* Register an API route handler. Call before starting server. */ 308 /* Register an API route handler. Call before starting server. */
94 extern void Seobeo_Router_Register(const char *method, const char *path_pattern, Seobeo_Route_Handler handler); 309 extern void Seobeo_Router_Register(const char *method, const char *path_pattern, Seobeo_Route_Handler handler);
95 /* Clean up router resources */ 310 /* Clean up router resources */