blob: bb953a040c632caa582af0caac4f2cd55e37c197 [file] [log] [blame] [raw]
#ifndef WEBSOCKETS_H
#define WEBSOCKETS_H
#include "http_request.h"
#include "http_response.h"
/**
The Websocket type is an opaque type used by the websocket API to provide
identify a specific Websocket connection and manage it's internal state.
*/
typedef struct Websocket ws_s;
/**
The protocol / service identifier for `libserver`.
*/
extern char* WEBSOCKET_ID_STR;
/**
The Websocket Handler contains all the settings required for new websocket
connections.
This struct is used for the named agruments in the `websocket_upgrade`
macro.
*/
typedef struct {
/**
The (optional) on_message callback will be called whenever a websocket message
is
received for this connection.
The data received points to the websocket's message buffer and it will be
overwritten once the function exits (it cannot be saved for later, but it can
be copied).
*/
void (*on_message)(ws_s* ws, char* data, size_t size, uint8_t is_text);
/**
The (optional) on_open callback will be called once the websocket connection
is
established.
*/
void (*on_open)(ws_s* ws);
/**
The (optional) on_shutdown callback will be called if a websocket connection
is still open while the server is shutting down (called before `on_close`).
*/
void (*on_shutdown)(ws_s* ws);
/**
The (optional) on_close callback will be called once a websocket connection is
terminated or failed to be established.
*/
void (*on_close)(ws_s* ws);
/** The `http_request_s` to be converted ("upgraded") to a websocket
* connection. Either a request or a response object is required.*/
http_request_s* request;
/**
The (optional) HttpResponse to be used for sending the upgrade response.
Using this object allows cookies to be set before "upgrading" the connection.
The ownership of the response object will remain unchanged - so if you have
created the response object, you should free it.
*/
http_response_s* response;
/**
The maximum websocket message size/buffer (in bytes) for this connection.
*/
size_t max_msg_size;
/** Opaque user data. */
void* udata;
/**
Timeout for the websocket connections, a ping will be sent
whenever the timeout is reached. Connections are only closed when a ping
cannot be sent (the network layer fails). Pongs aren't reviewed.
*/
uint8_t timeout;
} websocket_settings_s;
/** This macro allows easy access to the `websocket_upgrade` function. The macro
* allows the use of named arguments, using the `websocket_settings_s` struct
* members. i.e.:
*
* on_message(ws_s * ws, char * data, size_t size, int is_text) {
* ; // ... this is the websocket on_message callback
* websocket_write(ws, data, size, is_text); // a simple echo example
* }
*
* on_request(http_request_s* request) {
* websocket_upgrade( .request = request, .on_message = on_message);
* }
*
* Returns 0 on sucess and -1 on failure. A response is always sent.
*/
ssize_t websocket_upgrade(websocket_settings_s settings);
#define websocket_upgrade(...) \
websocket_upgrade((websocket_settings_s){__VA_ARGS__})
/** Returns the opaque user data associated with the websocket. */
void* websocket_get_udata(ws_s* ws);
/** Returns the the process specific connection's UUID (see `libsock`). */
intptr_t websocket_get_fduuid(ws_s* ws);
/** Sets the opaque user data associated with the websocket.
* Returns the old value, if any. */
void* websocket_set_udata(ws_s* ws, void* udata);
/** Writes data to the websocket. Returns -1 on failure (0 on success). */
int websocket_write(ws_s* ws, void* data, size_t size, uint8_t is_text);
/** Closes a websocket connection. */
void websocket_close(ws_s* ws);
/**
Performs a task on each websocket connection that shares the same process
(except the originating `ws_s` connection which is allowed to be NULL).
*/
void websocket_each(ws_s* ws_originator,
void (*task)(ws_s* ws_target, void* arg),
void* arg,
void (*on_finish)(ws_s* ws_originator, void* arg));
/**
Counts the number of websocket connections.
*/
size_t websocket_count(ws_s* ws);
#endif