Mercurial
comparison seobeo/seobeo.h @ 257:609d3c6aff4e
[seobeo] Add persistent SSE streams
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 04 Aug 2026 16:49:11 -0700 |
| parents | 117c4d53c9a4 |
| children | 1f9877b637e9 |
comparison
equal
deleted
inserted
replaced
| 256:30c2196d03d4 | 257:609d3c6aff4e |
|---|---|
| 25 #include <fcntl.h> | 25 #include <fcntl.h> |
| 26 #include <pthread.h> | 26 #include <pthread.h> |
| 27 | 27 |
| 28 | 28 |
| 29 #define INITIAL_BUFFER_CAPACITY 4096 | 29 #define INITIAL_BUFFER_CAPACITY 4096 |
| 30 #define SEOBEO_SSE_RETRY_NONE -1 | |
| 31 #define SEOBEO_SSE_EVENT_TOO_LARGE -2 | |
| 32 #define SEOBEO_SSE_INVALID_EVENT -3 | |
| 33 #define SEOBEO_SSE_BACKPRESSURE -4 | |
| 30 | 34 |
| 31 // HTTP STATUS CODE | 35 // HTTP STATUS CODE |
| 32 #define HTTP_OK 200 | 36 #define HTTP_OK 200 |
| 33 #define HTTP_CREATED 201 | 37 #define HTTP_CREATED 201 |
| 34 #define HTTP_NO_CONTENT 204 | 38 #define HTTP_NO_CONTENT 204 |
| 340 extern void Seobeo_Router_Init(); | 344 extern void Seobeo_Router_Init(); |
| 341 /* Register an API route handler. Call before starting server. */ | 345 /* Register an API route handler. Call before starting server. */ |
| 342 extern void Seobeo_Router_Register(const char *method, const char *path_pattern, Seobeo_Route_Handler handler); | 346 extern void Seobeo_Router_Register(const char *method, const char *path_pattern, Seobeo_Route_Handler handler); |
| 343 /* Register a streaming route handler. Handler receives client handle for direct streaming. */ | 347 /* Register a streaming route handler. Handler receives client handle for direct streaming. */ |
| 344 extern void Seobeo_Router_Register_Stream(const char *method, const char *path_pattern, Seobeo_Stream_Handler handler); | 348 extern void Seobeo_Router_Register_Stream(const char *method, const char *path_pattern, Seobeo_Stream_Handler handler); |
| 349 /* Register a GET route that owns an SSE stream until its handler returns. */ | |
| 350 extern void Seobeo_Router_Register_SSE(const char *path_pattern, Seobeo_SSE_Handler handler); | |
| 345 /* Clean up router resources */ | 351 /* Clean up router resources */ |
| 346 extern void Seobeo_Router_Destroy(); | 352 extern void Seobeo_Router_Destroy(); |
| 347 /* Find matching route handler (internal use) */ | 353 /* Find matching route handler (internal use) */ |
| 348 extern Seobeo_Route_Handler Seobeo_Router_Find_Handler(const char *method, const char *path, Seobeo_Request_Entry **pp_request_map, Dowa_Arena *p_arena); | 354 extern Seobeo_Route_Handler Seobeo_Router_Find_Handler(const char *method, const char *path, Seobeo_Request_Entry **pp_request_map, Dowa_Arena *p_arena); |
| 349 /* Send HTTP response from response map (internal use) */ | 355 /* Send HTTP response from response map (internal use) */ |
| 351 /* Send HTTP response with keep-alive option */ | 357 /* Send HTTP response with keep-alive option */ |
| 352 extern void Seobeo_Router_Send_Response_KeepAlive(Seobeo_Handle *p_handle, Seobeo_Request_Entry *p_response_map, Dowa_Arena *p_arena, boolean keep_alive); | 358 extern void Seobeo_Router_Send_Response_KeepAlive(Seobeo_Handle *p_handle, Seobeo_Request_Entry *p_response_map, Dowa_Arena *p_arena, boolean keep_alive); |
| 353 extern char *Seobeo_Web_LoadFile(const char *file_path, size_t *p_file_size); | 359 extern char *Seobeo_Web_LoadFile(const char *file_path, size_t *p_file_size); |
| 354 /* Being a proxy and keeping the client open */ | 360 /* Being a proxy and keeping the client open */ |
| 355 extern Seobeo_Stream_Handler Seobeo_Router_Find_Stream_Handler(const char *method, const char *path, Seobeo_Request_Entry **pp_request_map, Dowa_Arena *p_arena); | 361 extern Seobeo_Stream_Handler Seobeo_Router_Find_Stream_Handler(const char *method, const char *path, Seobeo_Request_Entry **pp_request_map, Dowa_Arena *p_arena); |
| 362 extern Seobeo_SSE_Handler Seobeo_Router_Find_SSE_Handler(const char *method, const char *path, Seobeo_Request_Entry **pp_request_map, Dowa_Arena *p_arena); | |
| 363 | |
| 364 /* Start an SSE response and send its required HTTP headers. */ | |
| 365 extern int32 Seobeo_SSE_Start(Seobeo_SSE_Stream *p_stream, Seobeo_Handle *p_handle); | |
| 366 /* Send one SSE record. retry_ms may be SEOBEO_SSE_RETRY_NONE. */ | |
| 367 extern int32 Seobeo_SSE_Send(Seobeo_SSE_Stream *p_stream, const Seobeo_SSE_Event *p_event); | |
| 368 /* Send a data-only SSE record. */ | |
| 369 extern int32 Seobeo_SSE_Send_Data(Seobeo_SSE_Stream *p_stream, const char *data); | |
| 370 /* Send a comment/heartbeat record. */ | |
| 371 extern int32 Seobeo_SSE_Send_Comment(Seobeo_SSE_Stream *p_stream, const char *comment); | |
| 372 /* Flush queued SSE bytes. Returns 1 when the socket would block. */ | |
| 373 extern int32 Seobeo_SSE_Flush(Seobeo_SSE_Stream *p_stream); | |
| 374 /* Return TRUE while the stream can still accept records. */ | |
| 375 extern boolean Seobeo_SSE_Is_Open(const Seobeo_SSE_Stream *p_stream); | |
| 376 /* Retain a stream before storing it beyond the connection callback. */ | |
| 377 extern boolean Seobeo_SSE_Retain(Seobeo_SSE_Stream *p_stream); | |
| 378 /* Release a previously retained stream. */ | |
| 379 extern void Seobeo_SSE_Release(Seobeo_SSE_Stream *p_stream); | |
| 380 /* Stop accepting records. The router retains ownership of the handle. */ | |
| 381 extern void Seobeo_SSE_Close(Seobeo_SSE_Stream *p_stream); | |
| 356 | 382 |
| 357 // --- Helper functions --- // | 383 // --- Helper functions --- // |
| 358 /* Destroy handle. It will handle all NULL poointers. */ | 384 /* Destroy handle. It will handle all NULL poointers. */ |
| 359 extern void Seobeo_Handle_Destroy(Seobeo_Handle *p_handle); | 385 extern void Seobeo_Handle_Destroy(Seobeo_Handle *p_handle); |
| 360 /* Write to socket from write_buffer in the handle. */ | 386 /* Write to socket from write_buffer in the handle. */ |
| 361 extern int Seobeo_Handle_Flush(Seobeo_Handle *p_handle); | 387 extern int32 Seobeo_Handle_Flush(Seobeo_Handle *p_handle); |
| 362 /* Write to socket with given data source, if the data source is bigger than the write buffer for handle then we just directly write from the data source. */ | 388 /* Write to socket with given data source, if the data source is bigger than the write buffer for handle then we just directly write from the data source. */ |
| 363 extern int Seobeo_Handle_Queue(Seobeo_Handle *p_handle, const uint8_t *data, uint32_t data_size); | 389 extern int32 Seobeo_Handle_Queue(Seobeo_Handle *p_handle, const uint8 *data, uint32 data_size); |
| 364 /* Read to socket from read_buffer in the handle. */ | 390 /* Read to socket from read_buffer in the handle. */ |
| 365 extern int Seobeo_Handle_Read(Seobeo_Handle *p_handle); | 391 extern int32 Seobeo_Handle_Read(Seobeo_Handle *p_handle); |
| 366 /* Move to read_buffer to front and we already consumed the given amount in the handle. */ | 392 /* Move to read_buffer to front and we already consumed the given amount in the handle. */ |
| 367 extern void Seobeo_Handle_Consume(Seobeo_Handle *p_handle, uint32 consumed); | 393 extern void Seobeo_Handle_Consume(Seobeo_Handle *p_handle, uint32 consumed); |
| 368 /* Assign IP4 or IP6 to sockaddr. TODO: Maybe create my own struct for this? */ | 394 /* Assign IP4 or IP6 to sockaddr. TODO: Maybe create my own struct for this? */ |
| 369 extern void *Seobeo_Get_IP4_Or_IP6(struct sockaddr *sa); | 395 extern void *Seobeo_Get_IP4_Or_IP6(struct sockaddr *sa); |
| 370 /* Logging */ | 396 /* Logging */ |