2. The Program

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

/*
 * server-core.c -- raw TCP echo server at the data layer (no WebSocket).
 *
 * vws_tcp_svr is the base server: it hands raw inbound bytes to an on_data_in
 * callback and ships raw bytes back. This also shows the per-worker thread
 * context (worker_ctor / worker_dtor) -- where a worker holds per-thread
 * resources (e.g. a database handle) that the data callback receives as its ctx.
 */

#include <vws/server.h>

#include "vwsx.h"

#include <stdio.h>
#include <string.h>

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

/* Per-worker context: created by the ctor, passed to on_data_in as ctx, freed
 * by the dtor. Here it is just a label, to show the lifecycle. */
static void* worker_ctor(void* data)
{
    (void)data;
    return vws.strdup("worker-ctx");
}

static void worker_dtor(void* ctx)
{
    vws.free(ctx);
}

/* Echo the raw inbound bytes back to the sender. Runs on a worker thread; ctx
 * is the per-worker context returned by worker_ctor. */
static void echo(vws_svr_data* req, void* ctx)
{
    (void)ctx;

    /* Copy the request bytes into a buffer the reply takes ownership of. */
    char* data = (char*)vws.malloc(req->size);
    memcpy(data, req->data, req->size);

    vws_svr_data* reply = vws_svr_data_own(req->server, req->cid,
                                           (ucstr)data, req->size);

    /* Free the request, then send the reply. */
    vws_svr_data_free(req);
    vws_tcp_svr_send(reply);
}

int main(void)
{
    vws_tcp_svr* server = vws_tcp_svr_new(10, 0, 0);

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

    server->on_data_in  = echo;
    server->worker_ctor = worker_ctor;
    server->worker_dtor = worker_dtor;

    /* The base server stops directly -- no cast needed here. */
    vwsx_serve_stop_on_signal(server);

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

    vws_tcp_svr_run(server, HOST, PORT);

    vws_tcp_svr_free(server);

    return 0;
}