* added more apis and ssl version with most examples * some make files ajusts * set close connection to false (7~10x better performance) in examples, added Async example with abort handler, added var in Makefile for capi library * added better comments and fixed CAPIHelloWorldASync sample * removed ssl and removed allocations * added make file * removed dynamic allocations * add rust example and rename other samples * remove make capi and make capi_examples from the main Makefile * remove capi targets from clean on main Makefile * add buffer solution for get header and some string_view values * added more Rust like sample * add void* user_data in all places with handlers * refactor to eliminate std::strncat * added SSL * added -fPIC to allow dynamic libraries to link (Python and Ruby needs) * removed uws_socket_context_options_t * removed uws_timer_t * fixed async examples * added shared library in makefile for python tests * fixed uws_res_end_without_body and added uws_get_loop_with_native * added libuv build * reverted unintended helloworld and helloworld threaded changes * cork tests * added uws_req_get_full_url, uws_req_for_each_header, uws_req_for_each_header * revert HttpResponse.h log changes * initial add for bun features (Thanks Jarred) * add uws_app_listen_domain, uws_app_listen_domain_with_options, uws_app_domain, and option to pass nullptr to http routes for dynamically removes * added uws_res_state, HttpResponse and WebSocket corkUnsafe + uncorkUnsafe * removing changes in HttpResponse and WebSocket * revert changes outside capi * new lines at the end revert * revert makefiles * revert makefiles last new line * revert makefiles last new line
157 lines
4.5 KiB
C
157 lines
4.5 KiB
C
#include "../libuwebsockets.h"
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#define SSL 1
|
|
|
|
|
|
//Timer close helper
|
|
void uws_timer_close(struct us_timer_t *timer)
|
|
{
|
|
struct us_timer_t *t = (struct us_timer_t *)timer;
|
|
struct timer_handler_data *data;
|
|
memcpy(&data, us_timer_ext(t), sizeof(struct timer_handler_data *));
|
|
free(data);
|
|
us_timer_close(t);
|
|
}
|
|
//Timer create helper
|
|
struct us_timer_t *uws_create_timer(int ms, int repeat_ms, void (*handler)(void *data), void *data)
|
|
{
|
|
struct us_loop_t *loop = uws_get_loop();
|
|
struct us_timer_t *delayTimer = us_create_timer(loop, 0, sizeof(void *));
|
|
|
|
struct timer_handler_data
|
|
{
|
|
void *data;
|
|
void (*handler)(void *data);
|
|
bool repeat;
|
|
};
|
|
|
|
struct timer_handler_data *timer_data = (struct timer_handler_data *)malloc(sizeof(timer_handler_data));
|
|
timer_data->data = data;
|
|
timer_data->handler = handler;
|
|
timer_data->repeat = repeat_ms > 0;
|
|
memcpy(us_timer_ext(delayTimer), &timer_data, sizeof(struct timer_handler_data *));
|
|
|
|
us_timer_set(
|
|
delayTimer, [](struct us_timer_t *t)
|
|
{
|
|
/* We wrote the pointer to the timer's extension */
|
|
struct timer_handler_data *data;
|
|
memcpy(&data, us_timer_ext(t), sizeof(struct timer_handler_data *));
|
|
|
|
data->handler(data->data);
|
|
|
|
if (!data->repeat)
|
|
{
|
|
free(data);
|
|
us_timer_close(t);
|
|
}
|
|
},
|
|
ms, repeat_ms);
|
|
|
|
return (struct us_timer_t *)delayTimer;
|
|
}
|
|
|
|
/* This is a simple WebSocket "sync" upgrade example.
|
|
* You may compile it with "WITH_OPENSSL=1 make" or with "make" */
|
|
|
|
/* ws->getUserData returns one of these */
|
|
struct PerSocketData {
|
|
/* Fill with user data */
|
|
};
|
|
|
|
int buffer_size(const char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
int result = vsnprintf(NULL, 0, format, args);
|
|
va_end(args);
|
|
return result + 1; // safe byte for \0
|
|
}
|
|
|
|
void listen_handler(struct us_listen_socket_t *listen_socket, uws_app_listen_config_t config, void* user_data)
|
|
{
|
|
if (listen_socket){
|
|
printf("Listening on port wss://localhost:%d\n", config.port);
|
|
}
|
|
}
|
|
|
|
void open_handler(uws_websocket_t* ws){
|
|
|
|
/* Open event here, you may access uws_ws_get_user_data(WS) which points to a PerSocketData struct */
|
|
uws_ws_subscribe(SSL, ws, "broadcast", 9);
|
|
}
|
|
|
|
void message_handler(uws_websocket_t* ws, const char* message, size_t length, uws_opcode_t opcode){
|
|
}
|
|
|
|
void close_handler(uws_websocket_t* ws, int code, const char* message, size_t length){
|
|
/* You may access uws_ws_get_user_data(ws) here, but sending or
|
|
* doing any kind of I/O with the socket is not valid. */
|
|
}
|
|
|
|
void drain_handler(uws_websocket_t* ws){
|
|
/* Check uws_ws_get_buffered_amount(ws) here */
|
|
}
|
|
|
|
void ping_handler(uws_websocket_t* ws, const char* message, size_t length){
|
|
/* You don't need to handle this one, we automatically respond to pings as per standard */
|
|
}
|
|
|
|
void pong_handler(uws_websocket_t* ws, const char* message, size_t length){
|
|
|
|
/* You don't need to handle this one either */
|
|
}
|
|
|
|
void on_timer_interval(void* data){
|
|
|
|
// broadcast the unix time as millis
|
|
|
|
uws_app_t * app = (uws_app_t *)data;
|
|
struct timespec ts;
|
|
timespec_get(&ts, TIME_UTC);
|
|
|
|
int64_t millis = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
|
|
|
|
|
char* message = (char*)malloc((size_t)buffer_size("%ld", millis));
|
|
size_t message_length = sprintf(message, "%ld", millis);
|
|
|
|
uws_publish(SSL, app, "broadcast", 9, message, message_length, uws_opcode_t::TEXT, false);
|
|
free(message);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
|
|
|
|
uws_app_t *app = uws_create_app(SSL, (struct us_socket_context_options_t){
|
|
/* There are example certificates in uWebSockets.js repo */
|
|
.key_file_name = "../misc/key.pem",
|
|
.cert_file_name = "../misc/cert.pem",
|
|
.passphrase = "1234"
|
|
});
|
|
|
|
uws_ws(SSL, app, "/*", (uws_socket_behavior_t){
|
|
.compression = uws_compress_options_t::SHARED_COMPRESSOR,
|
|
.maxPayloadLength = 16 * 1024,
|
|
.idleTimeout = 12,
|
|
.maxBackpressure = 1 * 1024 * 1024,
|
|
.upgrade = NULL,
|
|
.open = open_handler,
|
|
.message = message_handler,
|
|
.drain = drain_handler,
|
|
.ping = ping_handler,
|
|
.pong = pong_handler,
|
|
.close = close_handler,
|
|
});
|
|
|
|
uws_app_listen(SSL, app, 9001, listen_handler, NULL);
|
|
|
|
// broadcast the unix time as millis every 8 millis
|
|
uws_create_timer(8, 8, on_timer_interval, app);
|
|
|
|
uws_app_run(SSL, app);
|
|
} |