#include #include #include #include #include #include "../lib/libwebsockets.h" /* * libwebsocket Example server Copyright 2010 Andy Green * * Licensed under GPL2 * * Shows how to use libwebsocket */ #define LOCAL_RESOURCE_PATH "/usr/share/libwebsockets-test-server" static int port = 7681; static int ws_protocol = 76; static int use_ssl = 0; struct per_session_data { int number; }; /** * libwebsocket_callback() - User server actions * @wsi: Opaque websocket instance pointer * @reason: The reason for the call * @user: Pointer to per-session user data allocated by library * @in: Pointer used for some callback reasons * @len: Length set for some callback reasons * * This callback is the way the user controls what is served. All the * protocol detail is hidden and handled by the library. * * For each connection / session there is user data allocated that is * pointed to by "user". You set the size of this user data area when * the library is initialized with libwebsocket_create_server. * * You get an opportunity to initialize user data when called back with * LWS_CALLBACK_ESTABLISHED reason. * * LWS_CALLBACK_ESTABLISHED: after successful websocket handshake * LWS_CALLBACK_CLOSED: when the websocket session ends * LWS_CALLBACK_SEND: opportunity to send to client (you would use * libwebsocket_write() taking care about the * special buffer requirements * LWS_CALLBACK_RECEIVE: data has appeared for the server, it can be * found at *in and is len bytes long * LWS_CALLBACK_HTTP: an http request has come from a client that is not * asking to upgrade the connection to a websocket * one. This is a chance to serve http content, * for example, to send a script to the client * which will then open the websockets connection. * libwebsocket_get_uri() lets you find out the * URI path requested and * libwebsockets_serve_http_file() makes it very * simple to send back a file to the client. */ static int websocket_callback(struct libwebsocket * wsi, enum libwebsocket_callback_reasons reason, void * user, void *in, size_t len) { int n; char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + LWS_SEND_BUFFER_POST_PADDING]; char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING]; const char *uri; struct per_session_data * pss = user; switch (reason) { /* * Websockets session handshake completed and is established */ case LWS_CALLBACK_ESTABLISHED: fprintf(stderr, "Websocket connection established\n"); pss->number = 0; break; /* * Websockets session is closed */ case LWS_CALLBACK_CLOSED: fprintf(stderr, "Websocket connection closed\n"); break; /* * Opportunity for us to send something on the connection */ case LWS_CALLBACK_SEND: n = sprintf(p, "%d", pss->number++); n = libwebsocket_write(wsi, (unsigned char *)p, n, LWS_WRITE_TEXT); if (n < 0) { fprintf(stderr, "ERROR writing to socket"); exit(1); } break; /* * Something has arrived for us on the connection, it's len bytes long * and is available at *in */ case LWS_CALLBACK_RECEIVE: fprintf(stderr, "Received %d bytes payload\n", (int)len); break; /* * The client has asked us for something in normal HTTP mode, * not websockets mode. Normally it means we want to send * our script / html to the client, and when that script runs * it will start up separate websocket connections. * * Interpret the URI string to figure out what is needed to send */ case LWS_CALLBACK_HTTP: uri = libwebsocket_get_uri(wsi); fprintf(stderr, "serving HTTP URI %s\n", uri); if (uri && strcmp(uri, "/favicon.ico") == 0) { if (libwebsockets_serve_http_file(wsi, LOCAL_RESOURCE_PATH"/favicon.ico", "image/x-icon")) fprintf(stderr, "Failed to send favicon\n"); break; } /* send the script... when it runs it'll start websockets */ if (libwebsockets_serve_http_file(wsi, LOCAL_RESOURCE_PATH"/test.html", "text/html")) fprintf(stderr, "Failed to send HTTP file\n"); break; } return 0; } static struct option options[] = { { "help", no_argument, NULL, 'h' }, { "port", required_argument, NULL, 'p' }, { "protocol", required_argument, NULL, 'r' }, { "ssl", no_argument, NULL, 's' }, { NULL, 0, 0, 0 } }; int main(int argc, char **argv) { int n = 0; const char * cert_path = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem"; const char * key_path = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem"; fprintf(stderr, "libwebsockets test server\n" "Copyright 2010 Andy Green " "licensed under GPL2\n"); while (n >= 0) { n = getopt_long(argc, argv, "hp:r:", options, NULL); if (n < 0) continue; switch (n) { case 's': use_ssl = 1; break; case 'p': port = atoi(optarg); break; case 'r': ws_protocol = atoi(optarg); break; case 'h': fprintf(stderr, "Usage: test-server " "[--port=

] [--protocol=]\n"); exit(1); } } if (!use_ssl) cert_path = key_path = NULL; if (libwebsocket_create_server(port, websocket_callback, ws_protocol, sizeof(struct per_session_data), cert_path, key_path, -1, -1) < 0) { fprintf(stderr, "libwebsocket init failed\n"); return -1; } /* just sit there until killed */ while (1) sleep(10); return 0; }