Overview

This tutorial demonstrates how Mongoose Library can be used to implement a Websocket server that does the following:

  • Starts a listening HTTP server on port 8000
  • The /websocket URL serves a Websocket echo server
  • The /api/rest URL serves a RESTful server by responding with JSON string {"result": 123}
  • Any other URI serves static files from the current directory

A full source code for this tutorial is at https://github.com/cesanta/mongoose/tree/master/examples/websocket-server

Build and test

Assuming we're on a Mac or Linux workstation, start a new terminal and execute the following to build and start the example:

$ git clone https://github.com/cesanta/mongoose
$ cd mongoose/examples/websocket-server
$ make
cc ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1  -o example main.c
./example 
Starting WS listener on ws://localhost:8000/websocket

Start your browser on URL http://localhost:8000 - and you should see a directory listing. That's the static web server working:

static web server

Now change the URL to http://localhost:8000/rest - and you should see an output from the RESTful handler:

restful server

Now it's time to test a websocket server. In your browser, enter the URL http://localhost:8000/test.html:

WS server

Click on "Connect" button. In the textarea input field, type "hello" and click on "Send". You should see that message echoed back:

WS server

How it works

A Websocket server is basically a regular HTTP server which at some point switches protocol from HTTP to Websocket. In main() we set up a regular HTTP server:

And the secret sauce of turning HTTP server into a websocket server is in the event handler function:

There, we check the requested URI. If it is equal to /websocket, then we call an API function mg_ws_upgrade(). It turns HTTP connection to a Websocket connection. Websocket connection is full duplex, i.e. messages can be sent at any point by any side of the connection. Mongoose fires MG_EV_WS_MSG event when a message is received.

In this example, we catch incoming messages and echo them back: