Table of Contents:
A small Client-Side WebSocket library implemented in C.
Supports both ws and wss (if built with OpenSSL. see build options)
To install all dependencies for the project run ./install_deps.sh
Use the ./script/dev_deps.sh file to install system dependencies for the project.
These include libraries or tools needed to build the project.
Use the ./script/lib_deps.sh file to install library dependencies for the project.
These include libraries this library uses directly.
Required Deps:
- Zig The Zig programming language.
- cstd Common standard C functionality library.
- utf8-zig Small UTF8 helper library written in Zig.
Optional Deps:
- OpenSSL The OpenSSL library for secure
connections. Only used if ssl flag is on when building.
(
USE_SSL=1/-Duse_ssl)
Quickstart:
Both methods are basically the same except:
- Zig build option will build a wasm target library as well.
- Makefile will build the test application.
Makefile
make RELEASE=1 USE_SSL=1 SHARED=1Zig build:
zig build -Doptimize=ReleaseFast -Duse_ssl- Makefile (builds are put in
./bin)makeThe default will build the main test executable. The test executable uses normal connection by default.SHARED=1Will build the shared library for websocket-c.RELEASE=1Builds with optimizations turned on.USE_SSL=1Build with OpenSSL support. For the test executable it builds to usewss.DISABLE_SIMDForce disable SIMD functionality.
- Zig (builds are put in
./zig-out/lib)zig build -Doptimize=ReleaseFastBuilds the shared library and wasm library for websocket-c.-Duse_sslBuilds with OpenSSL support.-Ddisable_simdForce disable SIMD functionality.
To run the test application there is a Go application provided to run against.
- Build the test application with
maketo test non-secure functionality. - Inside the
test/serverdirectory you can build the Go application withgo build. - Then run the application from that directory with
./test. - Then from the root directory of the project run the test application with
./script/run.sh.
You will be presented with a prompt in the terminal whatever you type (up-to 100 characters) will be sent to the server and echoed back to you.
- Build the test application with
make USE_SSL=1to test secure functionality. - Inside the
test/directory run the./ssl_gen.shscript from that directory to generate aserver.crtcertificate andserver.keyprivate key to use with the server and client. - Inside the
test/serverdirectory you can build the Go application withgo build. - Then run the application from that directory with
sudo ./test tls. Thetlsargument will start a TLS server. - Then from the root directory of the project run the test application with
./script/run.sh.
You will be presented with a prompt in the terminal whatever you type (up-to 100 characters) will be sent to the server and echoed back to you.
Example of using your own listener loop.
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "websocket.h"
// URL
#define LISTENER_URL "ws://127.0.0.1:3000/ws"
int main(int argc, char **argv) {
// construct our client from the URL string.
struct ws_client_t client;
if (!ws_client_from_str(LISTENER_URL, strlen(LISTENER_URL), &client)) {
fprintf(stderr, "client from string URL failed.\n");
return 1;
}
// connect the client to the server.
if (!ws_client_connect(&client)) {
fprintf(stderr, "client failed to connect.\n");
return 1;
}
while (1) {
printf("waiting for messages...\n");
struct ws_message_t *msg = NULL;
// waiting for the next message to be received.
if (!ws_client_next_msg(&client, &msg)) {
fprintf(stderr, "client failed to recv.\n");
break;
}
if (msg == NULL) {
fprintf(stderr, "message was null\n");
break;
}
// handle message here
// free the message contents and the message.
ws_message_free(msg);
free(msg);
}
// free the client.
ws_client_free(&client);
return 0;
}Example of using the supplied ws_client_on_msg callback loop.
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "headers/reader.h"
#include "headers/websocket.h"
// URL
#define LISTENER_URL "ws://localhost:3000/ws"
static bool callback(struct ws_client_t *client, struct ws_message_t *msg, void *context) {
// handle the message
return true;
}
int main(int argc, char **argv) {
// construct our client from the URL string.
struct ws_client_t client;
if (!ws_client_from_str(LISTENER_URL, strlen(LISTENER_URL), &client)) {
fprintf(stderr, "client from string URL failed.\n");
return 1;
}
// connect the client to the server.
if (!ws_client_connect(&client)) {
fprintf(stderr, "client failed to connect.\n");
return 1;
}
printf("listening for messages...\n");
// blocking call to handle messages on the given callback
ws_client_on_msg(&client, callback, NULL);
// free.
ws_client_free(&client);
return 0;
}A simple example of using OpenSSL.
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "headers/reader.h"
#include "headers/websocket.h"
// URL
#define LISTENER_URL "wss://localhost:443/ws"
static bool callback(struct ws_client_t *client, struct ws_message_t *msg, void *context) {
// handle the message
return true;
}
int main(int argc, char **argv) {
// Initialize the OpenSSL functionality.
// This is an example of setting a self-signed cert.
// For publicly hosted server you can pass NULL.
net_init_client("./certs/server.crt", NULL);
// construct our client from the URL string.
struct ws_client_t client;
if (!ws_client_from_str(LISTENER_URL, strlen(LISTENER_URL), &client)) {
fprintf(stderr, "client from string URL failed.\n");
return 1;
}
// Connect the client to the server.
if (!ws_client_connect(&client)) {
fprintf(stderr, "client failed to connect.\n");
return 1;
}
printf("listening for messages...\n");
// blocking call to handle messages on the given callback
ws_client_on_msg(&client, callback, NULL);
// free client
ws_client_free(&client);
// deinitialize OpenSSL
net_deinit();
return 0;
}This is a small demo running the test application with TLS turned on.