Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple WebSocket server based on libwebsockets. For full description read http://martinsikora.com/libwebsockets-simple-websocket-server
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
window.WebSocket = window.WebSocket || window.MozWebSocket;
var websocket = new WebSocket('ws://127.0.0.1:9000',
'dumb-increment-protocol');
websocket.onopen = function () {
$('h1').css('color', 'green');
};
websocket.onerror = function () {
$('h1').css('color', 'red');
};
websocket.onmessage = function (message) {
console.log(message.data);
$('div').append($('<p>', { text: message.data }));
};
$('button').click(function(e) {
e.preventDefault();
websocket.send($('input').val());
$('input').val('');
});
});
</script>
</head>
<body>
<h1>WebSockets test</h1>
<form>
<input type="text" />
<button>Send</button>
</form>
<div></div>
</body>
</html>
#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");
break;
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
// http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n597
unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
LWS_SEND_BUFFER_POST_PADDING);
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
// http://stackoverflow.com/questions/5189071/print-part-of-char-array
printf("received data: %s, replying: %.*s\n", (char *) in, (int) len,
buf + LWS_SEND_BUFFER_PRE_PADDING);
// 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
free(buf);
break;
}
default:
break;
}
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,
libwebsocket_internal_extensions,
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)
}
libwebsocket_context_destroy(context);
return 0;
}
@doodzik

This comment has been minimized.

Copy link

commented Dec 18, 2013

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

"/Applications/Xcode.app/Contents/Developer/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
"/Applications/Xcode.app/Contents/Developer/usr/bin/make"  -f nbproject/Makefile-Debug.mk 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'?
                                          libwebsocket_internal_extensions,
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                          libwebsocket_get_internal_extensions
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libwebsockets.h:1108:55: 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/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libwebsockets.h:912:1: note: 'libwebsocket_create_context' declared here
LWS_VISIBLE LWS_EXTERN struct libwebsocket_context *
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libwebsockets.h:70:21: 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)
@boulabiar

This comment has been minimized.

Copy link

commented Mar 14, 2014

The library is modified and functions changed
I have also tested this but there still some errors otherwise.
http://stackoverflow.com/questions/15181265/libwebsockets-tutorial-issue-libwebsocket-internal-extensions-undeclared-and

This gist no more work with the new library.

@jimbo72

This comment has been minimized.

Copy link

commented May 23, 2014

Sorry for this stupid question, but how to compile ?
link http://martinsikora.com/libwebsockets-compiling-libraries-and-projects is down

@bjardnin

This comment has been minimized.

Copy link

commented Jun 25, 2015

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
https://gist.github.com/bjardnin/1df8cc5eb43ce5008f7e#file-libwebsockets-websocket-c

@linuxdeveloper

This comment has been minimized.

Copy link

commented Jul 8, 2015

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

@rragu

This comment has been minimized.

Copy link

commented Apr 22, 2016

Hi,

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 : https://github.com/warmcat/libwebsockets

Regards,
Ragu R

@Paul-Ver

This comment has been minimized.

Copy link

commented Jul 12, 2016

@zYeoman

This comment has been minimized.

Copy link

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.

@joeywu321

This comment has been minimized.

Copy link

commented Jun 20, 2017

@#zYeoman
Why i use your change.
But i test it by https://www.websocket.org/echo.html
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
You can’t perform that action at this time.