[Libwebsockets] How can I send async data using libwebsocket?
andy at warmcat.com
Mon Apr 12 07:31:29 CEST 2021
On 4/12/21 2:39 AM, Trung Do wrote:
> I am having the exact question as this stackoverflow one:
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
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
More information about the Libwebsockets