Libwebsockets
Jump to navigation
Jump to search
Environment
# cat /etc/debian_version 6.0.6 # gcc -v gcc version 4.4.5 (Debian 4.4.5-8) # uname -r 3.2.0-0.bpo.3-amd64
Build and install
NOTE: choose a destination path, I use /usr/local/libwebsockets
apt-get install libtool libssl-dev mkdir /usr/local/libwebsockets chown nobody:nogroup /usr/local/libwebsockets su -s /bin/bash nobody cd /tmp wget http://git.warmcat.com/cgi-bin/cgit/libwebsockets/snapshot/libwebsockets-788c4a8fa847ce7f6900e529af73f1aed7311ccc.tar.gz tar -xzf libwebsockets-788c4a8fa847ce7f6900e529af73f1aed7311ccc.tar.gz cd libwebsockets-788c4a8fa847ce7f6900e529af73f1aed7311ccc ./autogen.sh ./configure --prefix=/usr/local/libwebsockets --enable-openssl --enable-libcrypto make make install
First libwebsocket app
sources
from https://gist.github.com/3654228
- main.c:
#include <stdio.h> #include <stdlib.h> #include <libwebsockets.h> static int callback_http(struct libwebsocket_context * this_context, 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_context, 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, NULL); 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; }
- index.html
<!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>
Compile and run
gcc -o test main.c -I /usr/local/libwebsockets/include/ -L /usr/local/libwebsockets/lib/ -lwebsockets LD_LIBRARY_PATH=/usr/local/libwebsockets/lib ./test
Set-up an Eclipse CDT project =
Create an Eclipse project, maybe like there
Configure Index
- Project -> Properties
- C/C++ General -> Paths and Symbols
- switch to tab 'Includes'
- select 'GNU C++' an click 'Add...'
- Directory: "/usr/local/libwebsockets/include"
- click 'OK'
- switch to tab 'Library Paths'
- click 'Add...'
- Directory: "/usr/local/libwebsockets/lib"
- 'OK'
- click 'OK' again
Configure to Run and Debug
- Run -> Debug Configurations
- select 'C/C++ Application'
- click on 'New launch configuration'
- Name: "TestLibWebsockets Debug"
- C/C++ Application: "TestLibWebsockets/build/debug/TestLibWebsockets"
- switch to tab 'Environment'
- click New...
- Name: "LD_LIBRARY_PATH"
- Value: "/usr/local/libwebsockets/lib/"
- click Ok
- click on Close