WEBSOCKET CLIENT AND SERVER

What is WebSocket?

WebSockets are designed to be implemented in web browsers and servers and can be used by any client or server application. As web applications become more sophisticated, WebSocket is gaining popularity. It provides a way of building responsive and low-latency web applications by providing a persistent bidirectional communication channel between the client and the server in real-time. It’s an independent TCP-based protocol and a standardised way for a server to send content without being solicited by the client first. The connection between both can remain open.

Why is WebSocket important for connectivity?

Like HTTP, WebSocket is one of the most popular protocols in the world. However, unlike HTTP, WebSocket provides full-duplex communication. This means that after the initial handshake, each frame carries only a small header which reduces overhead compared to plain HTTP, and most importantly, it allows for server-initiated push of the data as it becomes available rather than have the client actively poll the server. This is often easier and less resource-intensive than using one channel for reporting and a second for controlling the device. Especially with increasing complexity of the control and reporting logic, the benefits of a bi-directional connection appear.

WebSocket and Mongoose Embedded Web Server

There are several ways to use WebSocket in Mongoose.

For an embedded WebSocket client use mg_ws_connect(). This function returns a WebSocket connection.

For an embedded WebSocket server, create HTTP listener then upgrade it to Websocket.

Mongoose provides a lot of helpers, for example, for parsing HTTP headers, serving files, parsing and composing addresses.

WebSocket server example

Create HTTP listener:

struct mg_connection *c = mg_http_listen(&mgr, "ws://127.0.0.1:8000", fn, NULL);

Upgrade protocol to Websocket and handle WebSocket events:

static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
  if (ev == MG_EV_HTTP_MSG) {
    // Got HTTP request. Upgrade to Websocket
    struct mg_http_message *hm = (struct mg_http_message *) ev_data;
     mg_ws_upgrade(c, hm);
  } else if (ev == MG_EV_WS_MSG) {
    // Got Websocket frame. Received data is wm->data
    struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
    ...
See full Websocket server example.

WebSocket client example

Make a connection:

mg_ws_connect(&mgr, "ws://server.com", fn, fn_data, NULL);

Then handle frames the same way as server code does.

See full Websocket server example.

Full list of examples