The server header and the examples' support header are included:
#include <vws/server.h> #include "vwsx.h"
The per-message hook echoes each inbound message. It receives the server,
the connection id, the incoming
vws_msg, and the worker context
(unused here):
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;
vws_buffer_append(reply->data, m->data->data, m->data->size);
server->send(server, cid, reply, NULL);
vws_msg_free(m);
}The reply is a new message that copies the incoming opcode — preserving
the message type — and appends the incoming payload with
vws_buffer_append(). It is sent through
the server's send member, which takes ownership of the reply
and frees it; the handler therefore frees only the incoming message, with
vws_msg_free().
The server is created in main and the handler is
installed on the correct hook:
vws_svr* server = vws_svr_new(10, 0, 0);
if (server == NULL)
{
vwsx_die("vws_svr_new() failed");
}
server->process_ws = echo;The handler is assigned to process_ws, the hook the
framework invokes for each decoded WebSocket message. It must not be assigned to
the server's internal on_msg_in dispatcher, which is the code
that calls process_ws.
Finally the server is wired to stop on a signal and run:
vwsx_serve_stop_on_signal((vws_tcp_svr*)server); vws_tcp_svr_run((vws_tcp_svr*)server, HOST, PORT); vws_svr_free(server);
A vws_svr embeds a
vws_tcp_svr as its first member and
is driven through that base: both the stop-on-signal helper and the blocking
vws_tcp_svr_run() are passed the server
through a (vws_tcp_svr*) cast. Only the base server exposes a stop
entry point — vws_tcp_svr_stop() — so a
derived server is always stopped through it. When the run returns,
vws_svr_free() releases the
server.