[Libwebsockets] client protocol selection criteria discussion

Olivier Langlois olivier at olivierlanglois.net
Sun Feb 16 04:32:50 CET 2020

On Mon, 2020-02-10 at 00:44 +0000, Andy Green wrote:
> On February 9, 2020 11:05:23 PM GMT, Olivier Langlois <
> olivier at olivierlanglois.net
> > wrote:
> > I feel like I am currently in uncharted waters in my lws usage and
> > I am
> > discovering the limits of what is possible as I figure out how to
> > accomplish my design goal.
> Lws is predicated around a single threaded event loop.  Its only way
> to interoperate with other threads is lws_cancel_service().
> That's a very simple proposition that goes a long way.  Lws doesn't
> claim anything to mislead you into thinking it's threadsafe and you
> can just call its apis from different threads - you can't.

Fair enough. you can have 1 thread per loop and this is how I intended
to use 2 threads with lws.
> > Here is some background to what I'm trying to accomplish:
> > 
> > 1. Have a client connect to 2 different services
> It's fine.
> > 2. Because I don't want 1 service handling impacting the
> > performance
> > and responsiveness of the other service handling, having 2 service
> > threads and have each connection binded to its own thread
> > exclusively
> > would be ideal
> In the lws part, with only two or a dozen streams on a capable
> microcontroller, it doesn't typically introduce much real latency
> over what the network traffic itself caused.  If your user code is
> going to block for cpu or anything else, it's possible to handle all
> the io as lws wants, put it into shared objects in memory and signal
> another thread something came / call lws_cancel_service() to alert
> lws something to do from another thread.  If you don't really expect
> your user code to block, try it all in the one service thread first.(
> That will all work fine if, eg, unknown to either of them your two
> client connections are h2 streams to the same endpoint sharing one
> network connection.

Again, I agree. 1 thread doing the LWS I/O for 2 connection won't
introduce much real latency. My latency concern is from each protocol
incoming message handling code than the I/O itself. The volume of
incoming messages can be susbtantially high.

An alternate design would be:

1 LWS thread dispatching messages to 2 worker threads. That would work

but as long as I am able to keep a simpler 2 threads design in the
real-time realm that is the road that I am favorising if allowed by LWS
simply because not having to pass the messages between threads would
keep the message handling latency lower.

> > 3. The 2 service are 2 different protocols.
> Doesn't make any difference.
> > I have found that if a connection was created from a service
> > thread, an
> > initial binding was created between the thread and the connection
> > (under which conditions could that binding be broken?).
> No that's something different.  You almost always use exactly one
> service thread, that's why a max of 1 is the default.  In the case
> you're the server and want to serve huge numbers of connections,
> load-balancing across n event loops on n threads / cores lets you
> scale beyond what a single thread can do.  It's still a single-
> threaded event loop, you just have n of them and new connections bind
> to the most idle one.  It's not what you want.

I agree that multiple service thread is usually reserved to server
design. My application message processing is that heavy. I'm confident
that a single connection can use 100% of its cpu. Therefore the most
obvious and easiest way to balance my processing load is to assign 1
connection to its dedicated thread.

> > However, the only criteria lws use to determine the protocol to use
> > is
> > the Protocol header value found in the server reply. Therefore, I
> > will
> Yeah that is how ws works.
> > be forced to use a single callback for my 2 protocols and do the
> > dispatching myself from the callback.
> Nope...
> https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-client.h#n119

That is awesome! thx for the pointer. I need to check how the server
will react by seeing the protocol name that I have assign to its API
service but if it just silently discard it an HS succeed as usual,
using local_protocol_name could do what I need. I will give it a try.
> > I am throwing this idea on the list for discussion. Would it be a
> > good
> > feature to make it possible to select the protocol based on the
> > connection destination?
> > 
> > ie: if you connect to protocolA server, use protocol A. if you
> > connect
> > to protocolB server, use protocol B.
> > 
> > Something that I need to mention. It is that I am developing a WS
> > client to use existing WS services. I suspect that I'm a rare breed
> > as
> Lots of people use lws with somebody else's apis.
That is good to know. I'm looking forward seeing what others are doing
with lws.

The only other projects that I'm aware of that are using lws are
mosquitto and csound

More information about the Libwebsockets mailing list