[Libwebsockets] New user questions

Tony Mountifield tony at softins.co.uk
Mon Sep 5 22:44:34 CEST 2016


Hi Andy, many thanks for your reply...

Andy Green <andy at warmcat.com> wrote:
> 
> On September 5, 2016 10:12:20 PM GMT+08:00, tony at softins.co.uk wrote:
> >Hi, I've just joined this list because I'm looking for somewhere to ask
> >questions from the point of view of an experienced programmer who is
> >completely new to libwebsockets. Please let me know if there is a more
> >appropriate place.
> >
> >I've just started to look at libwebsockets as a way to add websocket
> >handling to my multi-threaded application server as a replacement for
> >the
> >current architecture, which is AJAX long polling over HTTP to a simple
> >http server embedded in the application.
> >
> >I have two main questions:
> >
> >1. I see that libwebsockets is structured as a single thread with an
> >event loop and callbacks. So when I receive a message from the client,
> >it causes a callback function to be called, such as
> >callback_dumb_increment().
> >
> >In the examples I have seen, callback_dumb_increment() does a very
> >simple
> >string reversal and immediately returns the result as a message by
> 
> It... dumbly increments a number.

Ah, the example I found at http://usualcarrot.com/libwebsockets-simple-websocket-server
was doing what I described, but had not changed the callback name, nor the protocol
string. Presumably the protocol strings, such as "dumb-increment-protocol" and
"lws-command-protocol" are arbitrary, chosen by the implementor and only need
to be agreed between the client and the server?

> >calling
> >libwebsocket_write().
> >
> >Am I correct in assuming that this callback executes within the main
> >event
> >loop thread?
> 
> Yes.  There are two basic styles of doing this stuff, 'throw a thread at it', and a nonblocking event loop in a single thread.  Both are valid and have advantages and disadvantages.

Ok, yes.

> >What happens if the message handling needs to do something that will
> >take
> >some time, such as a database access, before it is able to send a
> >response? Does this cause ALL message handling for all connections to
> >be
> >stalled until the callback returns?
> 
> No, you would schedule the work to happen in parallel and immediately return
> to the event loop.  When the work completes, it would ask for a callback when
> the connection is writeable.  When the work completed AND the outward
> connection can accept more data, then the connection gets a callback and you
> can write your data.
> 
> The event loop remains serialized in one thread, and never blocked, not for
> the work and not in the case the ongoing connection became full.

Ok, that makes sense. So it is the incoming callback's responsibility to hand off
the operation that would block to a different worker thread.

> >I am used to having a separate execution thread for each open
> >connection,
> >so that when one of them is waiting for I/O, it doesn't block the
> >others,
> >and I'm having difficulty seeing how to achieve something similar with
> >the
> >single-threaded libwebsockets architecture.
> 
> The above method solves it.
> 
> >2. Other threads in my application generate events from time to time
> >that
> >need to be delivered to interested client connections. In the AJAX long
> >polling architecture, these events are put into a per-client queue that
> >then gets emptied and sent by a "poll" request from the client.
> >
> >It is one of the supposed advantages of a continuously-open websocket
> >that
> >such events could be sent to the client immediately over the socket
> >without waiting for a poll. But what I have read about libwebsockets so
> >far suggests to me that only the main thread is allowed to do
> >libwebsocket_write() calls (although I may easily have misunderstood).
> >So
> >do I need some kind of message concentrator to funnel the event
> >messages
> >through?
> 
> The critical primitive is usually the state of the outgoing connection, not
> whatever you want to make happen.  You may have an event locally, but
> actually you cannot do anything useful with it if the outgoing connection
> cannot accept more data.  In the threaded method, this basic truth remains
> implicit because the write blocks your connection thread.  With lws
> single-threaded event loop method, you explicitly ask for a callback (on the
> main lws thread context... but you may ask for it from any thread) when you
> can write something; the callback comes at the time of your local event
> happening AND when the outgoing socket may be written to.

Ok, so the worker thread I mentioned above could queue its answer as I do
at present, request the callback, and then when the callback is invoked
it could read the answer from the queue and write it to the websock.

> >The above questions no doubt betray my lack of knowledge about how
> >properly to use libwebsockets, but if anyone could answer or point me
> >to
> >any resources or examples that deal with such real-life scenarios and
> >not
> >just "Hello world" examples, I would be very grateful indeed.
> 
> Your threading, locking and integration are all out of scope for lws.  It's
> all different depending on the platform, threading library and application.
> 
> The only lws api primitive you need to do it is to ask for a callback when
> writeable, and this can be found in every example.
> 
> But from the sound of it you are already completely invested in spawning
> threads every time a connection happens, and the blocking paradigm.  You
> might be happier looking for another websocket library that is based on the
> same scheme and also just throws threads and blocks.  Event loops and
> threading are used successfully together in eg, desktop evnironments, so it's
> not strange to mix the models, but a major advantage of event loops for this
> kind of work is elimination of per-connection thread and locking overhead.
> You probably need to decide about if you want that or a threaded, blocking
> solution first.

OK, that's good advice, thanks! Are you aware of any other websocket
libraries, that might be implemented more on the single thread per socket
architecture?

I found a Wikipedia page listing websocket implementations, and noticed that
libwebsockets isn't listed. Maybe you could get it added! The page is at
https://en.wikipedia.org/wiki/Comparison_of_WebSocket_implementations
I'm going to take a look also at noPoll, which is listed there.

Cheers
Tony
-- 
Tony Mountifield
Work: tony at softins.co.uk - http://www.softins.co.uk
Play: tony at mountifield.org - http://tony.mountifield.org



More information about the Libwebsockets mailing list