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