2. The Program

The complete program follows. It is generated from server-ws.c in the companion examples repository.

/*
 * server-ws.c -- minimal WebSocket echo server (the WebSocket layer).
 *
 * Creates a vws_svr, wires the per-message hook (process_ws), and echoes every
 * inbound message back to its sender. Run this, then point client-basic (or any
 * WebSocket client) at ws://localhost:8181/websocket.
 */

#include <vws/server.h>

#include "vwsx.h"

#include <stdio.h>

static const char* HOST = "127.0.0.1";
static const int   PORT = 8181;

/*
 * Per-message hook. Runs in a worker thread. Echoes the inbound message back on
 * the same connection, preserving its opcode (text vs binary).
 */
static void echo(vws_svr* server, vws_cid_t cid, vws_msg* m, void* ctx)
{
    (void)ctx;

    vws_msg* reply = vws_msg_new();
    reply->opcode  = m->opcode;                          /* same format back  */
    vws_buffer_append(reply->data, m->data->data, m->data->size);

    /* send() takes ownership of reply and frees it. */
    server->send(server, cid, reply, NULL);

    /* We own the request. */
    vws_msg_free(m);
}

int main(void)
{
    vws_svr* server = vws_svr_new(10, 0, 0);

    if (server == NULL)
    {
        vwsx_die("vws_svr_new() failed");
    }

    server->process_ws = echo;

    /*
     * Stop gracefully on SIGINT/SIGTERM. The derived servers have no stop entry
     * of their own -- the helper wraps vws_tcp_svr_stop through the base via the
     * (vws_tcp_svr*) cast.
     */
    vwsx_serve_stop_on_signal((vws_tcp_svr*)server);

    printf("server-ws: echo server on ws://%s:%d/websocket (Ctrl-C to stop)\n",
           HOST, PORT);

    /*
     * Blocking run. A vws_svr is driven through its base handle: the base
     * run/stop (vws_tcp_svr_run / vws_tcp_svr_stop) operate on any server via
     * the (vws_tcp_svr*) cast, exactly as the canonical test does.
     */
    vws_tcp_svr_run((vws_tcp_svr*)server, HOST, PORT);

    vws_svr_free(server);

    return 0;
}