introduce-libwebsockets-test-server-extpoll.patch
authorAndy Green <andy.green@linaro.org>
Sat, 12 Feb 2011 12:07:23 +0000 (12:07 +0000)
committerAndy Green <andy.green@linaro.org>
Sat, 12 Feb 2011 12:07:23 +0000 (12:07 +0000)
Signed-off-by: Andy Green <andy.green@linaro.org>
test-server/Makefile.am
test-server/Makefile.in
test-server/test-server-extpoll.c [new file with mode: 0644]

index c94d313..a28fe1d 100644 (file)
@@ -1,12 +1,15 @@
-bin_PROGRAMS=libwebsockets-test-server libwebsockets-test-client
+bin_PROGRAMS=libwebsockets-test-server libwebsockets-test-client libwebsockets-test-server-extpoll
 libwebsockets_test_server_SOURCES=test-server.c
 libwebsockets_test_server_LDADD=-L../lib -lwebsockets
 libwebsockets_test_client_SOURCES=test-client.c
 libwebsockets_test_client_LDADD=-L../lib -lwebsockets
+libwebsockets_test_server_extpoll_SOURCES=test-server-extpoll.c
+libwebsockets_test_server_extpoll_LDADD=-L../lib -lwebsockets
 
 
 libwebsockets_test_server_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
 libwebsockets_test_client_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
+libwebsockets_test_server_extpoll_CFLAGS:= -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
 
 if NOPING
 else
index d6f0da6..2a9c7dc 100644 (file)
@@ -35,7 +35,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 bin_PROGRAMS = libwebsockets-test-server$(EXEEXT) \
-       libwebsockets-test-client$(EXEEXT) $(am__EXEEXT_1)
+       libwebsockets-test-client$(EXEEXT) \
+       libwebsockets-test-server-extpoll$(EXEEXT) $(am__EXEEXT_1)
 @NOPING_FALSE@am__append_1 = libwebsockets-test-ping
 subdir = test-server
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
@@ -78,6 +79,14 @@ libwebsockets_test_server_LINK = $(LIBTOOL) --tag=CC \
        $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
        $(libwebsockets_test_server_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
        $(LDFLAGS) -o $@
+am_libwebsockets_test_server_extpoll_OBJECTS = libwebsockets_test_server_extpoll-test-server-extpoll.$(OBJEXT)
+libwebsockets_test_server_extpoll_OBJECTS =  \
+       $(am_libwebsockets_test_server_extpoll_OBJECTS)
+libwebsockets_test_server_extpoll_DEPENDENCIES =
+libwebsockets_test_server_extpoll_LINK = $(LIBTOOL) --tag=CC \
+       $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+       $(libwebsockets_test_server_extpoll_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -93,10 +102,12 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        $(LDFLAGS) -o $@
 SOURCES = $(libwebsockets_test_client_SOURCES) \
        $(libwebsockets_test_ping_SOURCES) \
-       $(libwebsockets_test_server_SOURCES)
+       $(libwebsockets_test_server_SOURCES) \
+       $(libwebsockets_test_server_extpoll_SOURCES)
 DIST_SOURCES = $(libwebsockets_test_client_SOURCES) \
        $(am__libwebsockets_test_ping_SOURCES_DIST) \
-       $(libwebsockets_test_server_SOURCES)
+       $(libwebsockets_test_server_SOURCES) \
+       $(libwebsockets_test_server_extpoll_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -218,8 +229,11 @@ libwebsockets_test_server_SOURCES = test-server.c
 libwebsockets_test_server_LDADD = -L../lib -lwebsockets
 libwebsockets_test_client_SOURCES = test-client.c
 libwebsockets_test_client_LDADD = -L../lib -lwebsockets
+libwebsockets_test_server_extpoll_SOURCES = test-server-extpoll.c
+libwebsockets_test_server_extpoll_LDADD = -L../lib -lwebsockets
 libwebsockets_test_server_CFLAGS := -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
 libwebsockets_test_client_CFLAGS := -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
+libwebsockets_test_server_extpoll_CFLAGS := -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
 @NOPING_FALSE@libwebsockets_test_ping_SOURCES = test-ping.c
 @NOPING_FALSE@libwebsockets_test_ping_LDADD = -L../lib -lwebsockets
 @NOPING_FALSE@libwebsockets_test_ping_CFLAGS := -Wall -Werror -std=gnu99 -pedantic -DDATADIR=\"@datadir@\" -DLWS_OPENSSL_CLIENT_CERTS=\"@clientcertdir@\"
@@ -309,6 +323,9 @@ libwebsockets-test-ping$(EXEEXT): $(libwebsockets_test_ping_OBJECTS) $(libwebsoc
 libwebsockets-test-server$(EXEEXT): $(libwebsockets_test_server_OBJECTS) $(libwebsockets_test_server_DEPENDENCIES) 
        @rm -f libwebsockets-test-server$(EXEEXT)
        $(libwebsockets_test_server_LINK) $(libwebsockets_test_server_OBJECTS) $(libwebsockets_test_server_LDADD) $(LIBS)
+libwebsockets-test-server-extpoll$(EXEEXT): $(libwebsockets_test_server_extpoll_OBJECTS) $(libwebsockets_test_server_extpoll_DEPENDENCIES) 
+       @rm -f libwebsockets-test-server-extpoll$(EXEEXT)
+       $(libwebsockets_test_server_extpoll_LINK) $(libwebsockets_test_server_extpoll_OBJECTS) $(libwebsockets_test_server_extpoll_LDADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -319,6 +336,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_test_client-test-client.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_test_ping-test-ping.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_test_server-test-server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwebsockets_test_server_extpoll-test-server-extpoll.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -383,6 +401,20 @@ libwebsockets_test_server-test-server.obj: test-server.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_server_CFLAGS) $(CFLAGS) -c -o libwebsockets_test_server-test-server.obj `if test -f 'test-server.c'; then $(CYGPATH_W) 'test-server.c'; else $(CYGPATH_W) '$(srcdir)/test-server.c'; fi`
 
+libwebsockets_test_server_extpoll-test-server-extpoll.o: test-server-extpoll.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_server_extpoll_CFLAGS) $(CFLAGS) -MT libwebsockets_test_server_extpoll-test-server-extpoll.o -MD -MP -MF $(DEPDIR)/libwebsockets_test_server_extpoll-test-server-extpoll.Tpo -c -o libwebsockets_test_server_extpoll-test-server-extpoll.o `test -f 'test-server-extpoll.c' || echo '$(srcdir)/'`test-server-extpoll.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libwebsockets_test_server_extpoll-test-server-extpoll.Tpo $(DEPDIR)/libwebsockets_test_server_extpoll-test-server-extpoll.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='test-server-extpoll.c' object='libwebsockets_test_server_extpoll-test-server-extpoll.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_server_extpoll_CFLAGS) $(CFLAGS) -c -o libwebsockets_test_server_extpoll-test-server-extpoll.o `test -f 'test-server-extpoll.c' || echo '$(srcdir)/'`test-server-extpoll.c
+
+libwebsockets_test_server_extpoll-test-server-extpoll.obj: test-server-extpoll.c
+@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_server_extpoll_CFLAGS) $(CFLAGS) -MT libwebsockets_test_server_extpoll-test-server-extpoll.obj -MD -MP -MF $(DEPDIR)/libwebsockets_test_server_extpoll-test-server-extpoll.Tpo -c -o libwebsockets_test_server_extpoll-test-server-extpoll.obj `if test -f 'test-server-extpoll.c'; then $(CYGPATH_W) 'test-server-extpoll.c'; else $(CYGPATH_W) '$(srcdir)/test-server-extpoll.c'; fi`
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libwebsockets_test_server_extpoll-test-server-extpoll.Tpo $(DEPDIR)/libwebsockets_test_server_extpoll-test-server-extpoll.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='test-server-extpoll.c' object='libwebsockets_test_server_extpoll-test-server-extpoll.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libwebsockets_test_server_extpoll_CFLAGS) $(CFLAGS) -c -o libwebsockets_test_server_extpoll-test-server-extpoll.obj `if test -f 'test-server-extpoll.c'; then $(CYGPATH_W) 'test-server-extpoll.c'; else $(CYGPATH_W) '$(srcdir)/test-server-extpoll.c'; fi`
+
 mostlyclean-libtool:
        -rm -f *.lo
 
diff --git a/test-server/test-server-extpoll.c b/test-server/test-server-extpoll.c
new file mode 100644 (file)
index 0000000..cccb50e
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * libwebsockets-test-server-extpoll - libwebsockets external poll loop sample
+ *
+ * This acts the same as libwebsockets-test-server but works with the poll
+ * loop taken out of libwebsockets and into this app.  It's an example of how
+ * you can integrate libwebsockets polling into an app that already has its
+ * own poll loop.
+ *
+ * Copyright (C) 2010-2011 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation:
+ *  version 2.1 of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <sys/time.h>
+#include <poll.h>
+
+#include "../lib/libwebsockets.h"
+
+
+/*
+ * This demo server shows how to use libwebsockets for one or more
+ * websocket protocols in the same server
+ *
+ * It defines the following websocket protocols:
+ *
+ *  dumb-increment-protocol:  once the socket is opened, an incrementing
+ *                             ascii string is sent down it every 50ms.
+ *                             If you send "reset\n" on the websocket, then
+ *                             the incrementing number is reset to 0.
+ *
+ *  lws-mirror-protocol: copies any received packet to every connection also
+ *                             using this protocol, including the sender
+ */
+
+#define MAX_POLL_ELEMENTS 100
+struct pollfd pollfds[100];
+int count_pollfds = 0;
+
+
+enum demo_protocols {
+       /* always first */
+       PROTOCOL_HTTP = 0,
+
+       PROTOCOL_DUMB_INCREMENT,
+       PROTOCOL_LWS_MIRROR,
+
+       /* always last */
+       DEMO_PROTOCOL_COUNT
+};
+
+
+#define LOCAL_RESOURCE_PATH DATADIR"/libwebsockets-test-server"
+
+/* this protocol server (always the first one) just knows how to do HTTP */
+
+static int callback_http(struct libwebsocket *wsi,
+               enum libwebsocket_callback_reasons reason, void *user,
+                                                          void *in, size_t len)
+{
+       switch (reason) {
+       case LWS_CALLBACK_HTTP:
+               fprintf(stderr, "serving HTTP URI %s\n", (char *)in);
+
+               if (in && strcmp(in, "/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;
+
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+/* dumb_increment protocol */
+
+/*
+ * one of these is auto-created for each connection and a pointer to the
+ * appropriate instance is passed to the callback in the user parameter
+ *
+ * for this example protocol we use it to individualize the count for each
+ * connection.
+ */
+
+struct per_session_data__dumb_increment {
+       int number;
+};
+
+static int
+callback_dumb_increment(struct libwebsocket *wsi,
+                       enum libwebsocket_callback_reasons reason,
+                                              void *user, void *in, size_t len)
+{
+       int n;
+       unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
+                                                 LWS_SEND_BUFFER_POST_PADDING];
+       unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
+       struct per_session_data__dumb_increment *pss = user;
+
+       switch (reason) {
+
+       case LWS_CALLBACK_ESTABLISHED:
+               pss->number = 0;
+               break;
+
+       /*
+        * in this protocol, we just use the broadcast action as the chance to
+        * send our own connection-specific data and ignore the broadcast info
+        * that is available in the 'in' parameter
+        */
+
+       case LWS_CALLBACK_BROADCAST:
+               n = sprintf((char *)p, "%d", pss->number++);
+               n = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT);
+               if (n < 0) {
+                       fprintf(stderr, "ERROR writing to socket");
+                       return 1;
+               }
+               break;
+
+       case LWS_CALLBACK_RECEIVE:
+               fprintf(stderr, "rx %d\n", (int)len);
+               if (len < 6)
+                       break;
+               if (strcmp(in, "reset\n") == 0)
+                       pss->number = 0;
+               break;
+
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+
+/* lws-mirror_protocol */
+
+#define MAX_MESSAGE_QUEUE 64
+
+struct per_session_data__lws_mirror {
+       struct libwebsocket *wsi;
+       int ringbuffer_tail;
+};
+
+struct a_message {
+       void *payload;
+       size_t len;
+};
+
+static struct a_message ringbuffer[MAX_MESSAGE_QUEUE];
+static int ringbuffer_head;
+
+
+static int
+callback_lws_mirror(struct libwebsocket *wsi,
+                       enum libwebsocket_callback_reasons reason,
+                                              void *user, void *in, size_t len)
+{
+       int n;
+       struct per_session_data__lws_mirror *pss = user;
+
+       switch (reason) {
+
+       case LWS_CALLBACK_ESTABLISHED:
+               pss->ringbuffer_tail = ringbuffer_head;
+               pss->wsi = wsi;
+               break;
+
+       case LWS_CALLBACK_CLIENT_WRITEABLE:
+               if (pss->ringbuffer_tail != ringbuffer_head) {
+
+                       n = libwebsocket_write(wsi, (unsigned char *)
+                                  ringbuffer[pss->ringbuffer_tail].payload +
+                                  LWS_SEND_BUFFER_PRE_PADDING,
+                                  ringbuffer[pss->ringbuffer_tail].len,
+                                                               LWS_WRITE_TEXT);
+                       if (n < 0) {
+                               fprintf(stderr, "ERROR writing to socket");
+                               exit(1);
+                       }
+
+                       if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
+                               pss->ringbuffer_tail = 0;
+                       else
+                               pss->ringbuffer_tail++;
+
+                       if (((ringbuffer_head - pss->ringbuffer_tail) %
+                                 MAX_MESSAGE_QUEUE) < (MAX_MESSAGE_QUEUE - 15))
+                               libwebsocket_rx_flow_control(wsi, 1);
+
+                       libwebsocket_callback_on_writable(wsi);
+
+               }
+               break;
+
+       case LWS_CALLBACK_BROADCAST:
+               n = libwebsocket_write(wsi, in, len, LWS_WRITE_TEXT);
+               if (n < 0)
+                       fprintf(stderr, "mirror write failed\n");
+               break;
+
+       case LWS_CALLBACK_RECEIVE:
+
+               if (ringbuffer[ringbuffer_head].payload)
+                       free(ringbuffer[ringbuffer_head].payload);
+
+               ringbuffer[ringbuffer_head].payload =
+                               malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
+                                                 LWS_SEND_BUFFER_POST_PADDING);
+               ringbuffer[ringbuffer_head].len = len;
+               memcpy((char *)ringbuffer[ringbuffer_head].payload +
+                                         LWS_SEND_BUFFER_PRE_PADDING, in, len);
+               if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
+                       ringbuffer_head = 0;
+               else
+                       ringbuffer_head++;
+
+               if (((ringbuffer_head - pss->ringbuffer_tail) %
+                                 MAX_MESSAGE_QUEUE) > (MAX_MESSAGE_QUEUE - 10))
+                       libwebsocket_rx_flow_control(wsi, 0);
+
+               libwebsocket_callback_on_writable_all_protocol(
+                                              libwebsockets_get_protocol(wsi));
+               break;
+
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+
+/* list of supported protocols and callbacks */
+
+static struct libwebsocket_protocols protocols[] = {
+       /* first protocol must always be HTTP handler */
+       [PROTOCOL_HTTP] = {
+               .name = "http-only",
+               .callback = callback_http,
+       },
+       [PROTOCOL_DUMB_INCREMENT] = {
+               .name = "dumb-increment-protocol",
+               .callback = callback_dumb_increment,
+               .per_session_data_size =
+                               sizeof(struct per_session_data__dumb_increment),
+       },
+       [PROTOCOL_LWS_MIRROR] = {
+               .name = "lws-mirror-protocol",
+               .callback = callback_lws_mirror,
+               .per_session_data_size =
+                               sizeof(struct per_session_data__lws_mirror),
+       },
+       [DEMO_PROTOCOL_COUNT] = {  /* end of list */
+               .callback = NULL
+       }
+};
+
+static struct option options[] = {
+       { "help",       no_argument,            NULL, 'h' },
+       { "port",       required_argument,      NULL, 'p' },
+       { "ssl",        no_argument,            NULL, 's' },
+       { "killmask",   no_argument,            NULL, 'k' },
+       { 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";
+       unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 1024 +
+                                                 LWS_SEND_BUFFER_POST_PADDING];
+       int port = 7681;
+       int use_ssl = 0;
+       struct libwebsocket_context *context;
+       int opts = 0;
+       unsigned int oldus = 0;
+
+       fprintf(stderr, "libwebsockets test server with external poll()\n"
+                       "(C) Copyright 2010-2011 Andy Green <andy@warmcat.com> "
+                                                   "licensed under LGPL2.1\n");
+
+       while (n >= 0) {
+               n = getopt_long(argc, argv, "khsp:", options, NULL);
+               if (n < 0)
+                       continue;
+               switch (n) {
+               case 's':
+                       use_ssl = 1;
+                       break;
+               case 'k':
+                       opts = LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK;
+                       break;
+               case 'p':
+                       port = atoi(optarg);
+                       break;
+               case 'h':
+                       fprintf(stderr, "Usage: test-server "
+                                            "[--port=<p>] [--ssl]\n");
+                       exit(1);
+               }
+       }
+
+       if (!use_ssl)
+               cert_path = key_path = NULL;
+
+       context = libwebsocket_create_context(port, protocols, cert_path,
+                                               key_path, -1, -1, opts);
+       if (context == NULL) {
+               fprintf(stderr, "libwebsocket init failed\n");
+               return -1;
+       }
+
+       buf[LWS_SEND_BUFFER_PRE_PADDING] = 'x';
+
+       /*
+        * This is an example of an existing application's explicit poll()
+        * loop that libwebsockets can integrate with.
+        */
+
+       while (1) {
+               struct timeval tv;
+
+               /*
+                * this represents an existing server's single poll action
+                * which also includes libwebsocket sockets
+                */
+
+               n = poll(pollfds, count_pollfds, 25);
+               if (n < 0)
+                       goto done;
+
+               if (n)
+                       for (n = 0; n < count_pollfds; n++)
+                               if (pollfds[n].revents)
+                                       /*
+                                       * returns immediately if the fd does not
+                                       * match anything under libwebsockets
+                                       * control
+                                       */
+                                       libwebsocket_service_fd(context,
+                                                                  &pollfds[n]);
+
+               /* do our broadcast periodically */
+
+               gettimeofday(&tv, NULL);
+
+               /*
+                * This broadcasts to all dumb-increment-protocol connections
+                * at 20Hz.
+                *
+                * We're just sending a character 'x', in these examples the
+                * callbacks send their own per-connection content.
+                *
+                * You have to send something with nonzero length to get the
+                * callback actions delivered.
+                *
+                * We take care of pre-and-post padding allocation.
+                */
+
+               if (((unsigned int)tv.tv_usec - oldus) > 50000) {
+                       libwebsockets_broadcast(
+                                       &protocols[PROTOCOL_DUMB_INCREMENT],
+                                       &buf[LWS_SEND_BUFFER_PRE_PADDING], 1);
+                       oldus = tv.tv_usec;
+               }
+       }
+
+done:
+       libwebsocket_context_destroy(context);
+
+       return 0;
+}