Skip to content

Instantly share code, notes, and snippets.

Created September 6, 2012 10:03
Show Gist options
  • Save martinsik/3654228 to your computer and use it in GitHub Desktop.
Save martinsik/3654228 to your computer and use it in GitHub Desktop.
Simple WebSocket server based on libwebsockets. For full description read
<!DOCTYPE html>
<meta charset="utf-8">
<script src=""></script>
<script type="text/javascript">
$(function() {
window.WebSocket = window.WebSocket || window.MozWebSocket;
var websocket = new WebSocket('ws://',
websocket.onopen = function () {
$('h1').css('color', 'green');
websocket.onerror = function () {
$('h1').css('color', 'red');
websocket.onmessage = function (message) {
$('div').append($('<p>', { text: }));
$('button').click(function(e) {
<h1>WebSockets test</h1>
<input type="text" />
#include <stdio.h>
#include <stdlib.h>
#include <libwebsockets.h>
static int callback_http(struct libwebsocket_context * this,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len)
return 0;
static int callback_dumb_increment(struct libwebsocket_context * this,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason,
void *user, void *in, size_t len)
switch (reason) {
case LWS_CALLBACK_ESTABLISHED: // just log message that someone is connecting
printf("connection established\n");
case LWS_CALLBACK_RECEIVE: { // the funny part
// create a buffer to hold our response
// it has to have some pre and post padding. You don't need to care
// what comes there, libwebsockets will do everything for you. For more info see
unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
int i;
// pointer to `void *in` holds the incomming request
// we're just going to put it in reverse order and put it in `buf` with
// correct offset. `len` holds length of the request.
for (i=0; i < len; i++) {
buf[LWS_SEND_BUFFER_PRE_PADDING + (len - 1) - i ] = ((char *) in)[i];
// log what we recieved and what we're going to send as a response.
// that disco syntax `%.*s` is used to print just a part of our buffer
printf("received data: %s, replying: %.*s\n", (char *) in, (int) len,
// send response
// just notice that we have to tell where exactly our response starts. That's
// why there's `buf[LWS_SEND_BUFFER_PRE_PADDING]` and how long it is.
// we know that our response has the same length as request because
// it's the same message in reverse order.
libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], len, LWS_WRITE_TEXT);
// release memory back into the wild
return 0;
static struct libwebsocket_protocols protocols[] = {
/* first protocol must always be HTTP handler */
"http-only", // name
callback_http, // callback
0 // per_session_data_size
"dumb-increment-protocol", // protocol name - very important!
callback_dumb_increment, // callback
0 // we don't use any per session data
NULL, NULL, 0 /* End of list */
int main(void) {
// server url will be http://localhost:9000
int port = 9000;
const char *interface = NULL;
struct libwebsocket_context *context;
// we're not using ssl
const char *cert_path = NULL;
const char *key_path = NULL;
// no special options
int opts = 0;
// create libwebsocket context representing this server
context = libwebsocket_create_context(port, interface, protocols,
cert_path, key_path, -1, -1, opts);
if (context == NULL) {
fprintf(stderr, "libwebsocket init failed\n");
return -1;
printf("starting server...\n");
// infinite loop, to end this server send SIGTERM. (CTRL+C)
while (1) {
libwebsocket_service(context, 50);
// libwebsocket_service will process all waiting events with their
// callback functions and then wait 50 ms.
// (this is a single threaded webserver and this will keep our server
// from generating load while there are not requests to process)
return 0;
Copy link

doodzik commented Dec 18, 2013

when i'm compiling libwebsockets-websocket.c i get this error:

"/Applications/" -f nbproject/ QMAKE= SUBPROJECTS= .build-conf
"/Applications/"  -f nbproject/ dist/Debug/GNU-MacOSX/cppapplication_3
mkdir -p build/Debug/GNU-MacOSX
rm -f build/Debug/GNU-MacOSX/main.o.d
gcc    -c -g -MMD -MP -MF build/Debug/GNU-MacOSX/main.o.d -o build/Debug/GNU-MacOSX/main.o main.c
main.c:97:43: error: use of undeclared identifier 'libwebsocket_internal_extensions'; did you mean 'libwebsocket_get_internal_extensions'?
/Applications/ note: 'libwebsocket_get_internal_extensions' declared here
LWS_VISIBLE LWS_EXTERN struct libwebsocket_extension *libwebsocket_get_internal_extensions();
main.c:96:49: error: too many arguments to function call, expected single argument 'info', have 9 arguments
    context = libwebsocket_create_context(port, interface, protocols,
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~       ^~~~~~~~~~~~~~~~~~~~~
/Applications/ note: 'libwebsocket_create_context' declared here
LWS_VISIBLE LWS_EXTERN struct libwebsocket_context *
/Applications/ note: expanded from macro 'LWS_VISIBLE'
#define LWS_VISIBLE __attribute__((visibility("default")))
2 errors generated.
make[2]: *** [build/Debug/GNU-MacOSX/main.o] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 234ms)

Copy link

The library is modified and functions changed
I have also tested this but there still some errors otherwise.

This gist no more work with the new library.

Copy link

jimbo72 commented May 23, 2014

Sorry for this stupid question, but how to compile ?
link is down

Copy link

There seems to be a change in the libwebsockets api, in case of interest, you can check my fork where the code is adjusted to new api

Copy link

How to change C source file for using my own IP address instead of localhost?

Copy link

rragu commented Apr 22, 2016


We are using CentOS release 6.7 (Final) version. Can someone please provide the steps to build libwebsocket server (C++). It would be more helpful for us and the response is more appreciated.
Git Path :

Ragu R

Copy link

mAPBhlJ commented Jul 12, 2016

Copy link

zYeoman commented Feb 16, 2017

There was a change in the libwebsockets api. New API: libwebsocket_* -> lws_*, and callback function without this.

You can check My fork, which works under version 2.1.0.

Copy link

joeywu321 commented Jun 20, 2017

Why i use your change.
But i test it by
I still can't run in LWS_CALLBACK_ESTABLISHED?
Only LWS_CALLBACK_PROTOCOL_INIT reson in callback_dumb_increment(...).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment