diff options
author | turret <turret@duck.com> | 2024-01-17 19:13:16 +0000 |
---|---|---|
committer | turret <turret@duck.com> | 2024-01-17 19:13:16 +0000 |
commit | d5c873a780357928fcccb27f4378b456f0e45dd2 (patch) | |
tree | 3b9eb7afb7ee0a6be89553f8c535b9274807e55e /net/ws.c | |
parent | 73d88e106fa0e85c5c2d100787fb640617b04798 (diff) | |
download | discord-bot-skeleton-d5c873a780357928fcccb27f4378b456f0e45dd2.tar.gz discord-bot-skeleton-d5c873a780357928fcccb27f4378b456f0e45dd2.tar.bz2 discord-bot-skeleton-d5c873a780357928fcccb27f4378b456f0e45dd2.zip |
net: basic ws handler
includes heartbeat mechanism
Diffstat (limited to 'net/ws.c')
-rw-r--r-- | net/ws.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/net/ws.c b/net/ws.c new file mode 100644 index 0000000..9ad857d --- /dev/null +++ b/net/ws.c @@ -0,0 +1,61 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> + +#include <cJSON.h> +#include <curl/curl.h> + +#include <log.h> + +extern CURL *ws_handle; +long last_sequence = -1; +struct timeval heartbeat_time; + +void ws_send_heartbeat() +{ + char buf[128] = "{\"op\":1,\"d\":null}"; + if(last_sequence > 0) + snprintf(buf, 128, "{\"op\":1,\"d\":%ld}", last_sequence); + size_t sent; + curl_ws_send(ws_handle, buf, strnlen(buf, 128), &sent, 0, CURLWS_TEXT); + + struct itimerval itimer; + getitimer(ITIMER_REAL, &itimer); + if(itimer.it_value.tv_sec < heartbeat_time.tv_sec - 2) { + itimer.it_value = heartbeat_time; + setitimer(ITIMER_REAL, &itimer, NULL); + } +} + +void ws_handle_event(cJSON *event) +{ + int op = cJSON_GetObjectItem(event, "op")->valueint; + switch(op) { + case 1: /* Heartbeat request */ + ws_send_heartbeat(); + break; + case 10: ; /* Hello */ + int heartbeat_wait = cJSON_GetObjectItem(cJSON_GetObjectItem(event, "d"), "heartbeat_interval")->valueint; + float jitter = (float)rand() / (RAND_MAX * 1.0f); + + heartbeat_time.tv_sec = heartbeat_wait / 1000; + heartbeat_time.tv_usec = (heartbeat_wait % 1000) * 1000; + struct timeval jitter_time = { + .tv_sec = heartbeat_time.tv_sec * jitter, + .tv_usec = heartbeat_time.tv_usec * jitter, + }; + struct itimerval new_itimer = { + .it_interval = heartbeat_time, + .it_value = jitter_time + }; + setitimer(ITIMER_REAL, &new_itimer, NULL); + break; + case 11: + break; + default: + print(LOG_ERR "ws: received unknown WS opcode %d", op); + break; + } +} |