blob: c8f4786cf9acc7e1a62140fad0e28fa165f1ba50 [file] [log] [blame] [raw]
// update the demo.c file to use the existing folder structure and makefile
#include "websockets.h" // includes the "http.h" header
#include <stdio.h>
#include <stdlib.h>
#include "bscrypt.h"
/*****************************
The Websocket echo implementation
*/
void ws_open(ws_s* ws) {
fprintf(stderr, "Opened a new websocket connection (%p)\n", ws);
}
void ws_echo(ws_s* ws, char* data, size_t size, uint8_t is_text) {
// echos the data to the current websocket
websocket_write(ws, data, size, 1);
}
void ws_shutdown(ws_s* ws) {
websocket_write(ws, "Shutting Down", 13, 1);
}
void ws_close(ws_s* ws) {
fprintf(stderr, "Closed websocket connection (%p)\n", ws);
}
/*****************************
The Websocket Broadcast implementation
*/
/* websocket broadcast data */
struct ws_data {
size_t size;
char data[];
};
/* free the websocket broadcast data */
void free_wsdata(ws_s* ws, void* arg) {
free(arg);
}
/* the broadcast "task" performed by `Websocket.each` */
void ws_get_broadcast(ws_s* ws, void* arg) {
struct ws_data* data = arg;
websocket_write(ws, data->data, data->size, 1); // echo
}
/* The websocket broadcast server's `on_message` callback */
void ws_broadcast(ws_s* ws, char* data, size_t size, uint8_t is_text) {
// Copy the message to a broadcast data-packet
struct ws_data* msg = malloc(sizeof(*msg) + size);
msg->size = size;
memcpy(msg->data, data, size);
// Asynchronously calls `ws_get_broadcast` for each of the websockets
// (except this one)
// and calls `free_wsdata` once all the broadcasts were perfomed.
websocket_each(ws, ws_get_broadcast, msg, free_wsdata);
// echos the data to the current websocket
websocket_write(ws, data, size, 1);
}
/*****************************
The HTTP implementation
*/
void on_request(http_request_s* request) {
// to log we will start a response.
http_response_s response = http_response_init(request);
// http_response_log_start(&response);
// upgrade requests to broadcast will have the following properties:
if (request->upgrade && !strcmp(request->path, "/broadcast")) {
// Websocket upgrade will use our existing response (never leak responses).
websocket_upgrade(.request = request, .on_message = ws_broadcast,
.on_open = ws_open, .on_close = ws_close,
.on_shutdown = ws_shutdown, .response = &response);
return;
}
// other upgrade requests will have the following properties:
if (request->upgrade) {
websocket_upgrade(.request = request, .on_message = ws_echo,
.on_open = ws_open, .on_close = ws_close, .timeout = 4,
.on_shutdown = ws_shutdown, .response = &response);
return;
}
// HTTP response
http_response_write_body(&response, "Hello World!", 12);
http_response_finish(&response);
}
/*****************************
The main function
*/
#define THREAD_COUNT 0
int main(int argc, char const* argv[]) {
const char* public_folder = "./public_www";
http1_listen("3000", NULL, .on_request = on_request,
.public_folder = public_folder, .log_static = 1);
server_run(.threads = THREAD_COUNT);
return 0;
}