[Libwebsockets] How can I send async data using libwebsocket?

Andy Green andy at warmcat.com
Mon Apr 12 07:31:29 CEST 2021



On 4/12/21 2:39 AM, Trung Do wrote:
> Hello,
> 
> I am having the exact question as this stackoverflow one:
> 
> https://stackoverflow.com/questions/14261076/how-do-i-send-async-data-via-libwebsocket

Well, at least you're asking it in the right place.

> In short, after having connected a websocket client to a server, how
> can I send data to the server at any time I want, instead of just in

Neither you nor anybody else can "send data to the server any time 
[they] want".  You might be able to send a packet if your connectivity, 
network conditions, and the remote peer permit it.  But nobody has the 
spare memory to deal with huge mountains of data you wanted to naively 
issue that could not be forwarded or at least lined up for forwarding 
more or less immediately.

This network programming reality is the same with or without blocking 
semantics.  With blocking your thread is just blocked until you're 
actually able to send something, it's not visible in the code but 
write() or send() suffers unlimited narcolepsy when it is disallowed 
from sending anything.  In fact a way to make timeouts becomes a problem 
with blocking semantics since your sending thread has no upper limit on 
how long it can be forcibly blocked waiting to actually be able to send 
the next piece.  And it's just inert and unable to do anything else 
while blocked.

Because the threads block for most of their life, blocking doesn't scale 
either since you must have an OS thread per connection, just so it can 
block for when it can send something next to maintain this delusion that 
the user code can loop "sending as much as it wants".

> the callback that gets called when the server sends me something?

In nonblocking event loops, you are informed when you can send again on 
that connection with an event.  The rest of the time while waiting for 
that, your thread can be busy with other connections or other work.

Blocking is like "please hold", and nonblocking is "I'll call you back".

> There was one answer in that stackoverflow link but it's from 2013 and
> I'm not sure if it's the correct/recommended approach, plus a lot of
> the method names have changed. I have digged through the examples but
> haven't found anything for this use case.

Unfortunately there's a lot of cruft there that I neither wrote nor 
control.  But there are the minimal examples in-tree the last few years 
that show the recent best practice.

You won't find anything for this "use case" because that is not how 
nonblocking event loops work.  You should accept your sending action is 
like a per-wsi state machine inside the WRITEABLE callback.  If you 
can't get your head around it, well, ok, there are probably other libs 
out there that offer blocking apis.  But AFAIK the others are also 
nonblocking event loop based, because it is significantly superior.

If you actually wanted to ask "how can I ask for the writeable callback 
on connections from another thread", look at ws-server-threads

https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/ws-server/minimal-ws-server-threads/protocol_lws_minimal.c#n124

https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/ws-server/minimal-ws-server-threads/protocol_lws_minimal.c#n124-266

-Andy


More information about the Libwebsockets mailing list