summaryrefslogtreecommitdiff
path: root/test-server
diff options
context:
space:
mode:
Diffstat (limited to 'test-server')
-rw-r--r--test-server/Makefile.am5
-rw-r--r--test-server/Makefile.in38
-rw-r--r--test-server/test-server-extpoll.c406
3 files changed, 445 insertions, 4 deletions
diff --git a/test-server/Makefile.am b/test-server/Makefile.am
index c94d313..a28fe1d 100644
--- a/test-server/Makefile.am
+++ b/test-server/Makefile.am
@@ -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
diff --git a/test-server/Makefile.in b/test-server/Makefile.in
index d6f0da6..2a9c7dc 100644
--- a/test-server/Makefile.in
+++ b/test-server/Makefile.in
@@ -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
index 0000000..cccb50e
--- /dev/null
+++ b/test-server/test-server-extpoll.c
@@ -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;
+}