[Libwebsockets] How to send data asynchronously to the client?

Andy Green andy at warmcat.com
Sat Jul 5 05:43:21 CEST 2014



On 06/27/2014 10:16 PM, Bas Appelo wrote:
> Oopz, sorry, other email client does wrong email on reply....
>
> -------- Original Message --------
> Subject: 	Re: [Libwebsockets] How to send data asynchronously to the
> client?
> Date: 	Thu, 26 Jun 2014 21:45:24 +0200
> From: 	Bas Appelo <bas at appelo.nl>
> To: 	Mike M <andy.green at linaro.org>
>
>
>
> Hi All,
>
> Two things, first the cancel is not thread-unsafe, it nicely writes to a
> pipe which is being polled, so I will keep using this, and consider it
> thread safe.
>
> But :(
>
> I don’t really understand what Andy means with this:
>>>>>> >Libwebsockets is basically single-threaded.  But, with care from another
>>>>>> >server thread, you can call either
> What does ‘With care’ means, I rewrote my code so that it doesn’t call
> service_cancel, but skips that and now does

It means there is deliberately zero threadsafety / locking in this 
library and if you approach it like there is, it will blow up.

It's designed to have a single service thread so it is very unusually 
efficient and lightweight and can be used on very small and weak devices 
with low footprint.

It just happens that if you follow that architecture with your code, 
it's also very very efficient with large numbers of connections too.

> libwebsocket_callback_on_writable(context, wsi) from what I called
> thread-2. This works! But only the first time (could be because then
> there is also other traffic…) But in a quite environment, I can see it
> does something, but I’m not receiving LWS_CALLBACK_SERVER_WRITEABLE.

We got a contribution a few months ago that redid the guts of all this 
to use the pipe.  So it is supposed to work now just by calling the 
writeable callback from another thread context (it will discover that is 
happening by checking your thread ID).

> I’m doing this, because I’m still having issues with my first approach,
> it works like charm in a single libwebsocket_context, but if I create
> two, I’m not receiving any LWS_CALLBACK_SERVER_WRITEABLE, with both
> approaches (cancel thread-2 libwebsocket_callback_on_writable thread-1
> or libwebsocket_callback_on_writable thread -2)
>
> If you would like any additional info (like a small prog that reproduces
> this, or the dump logging (which don’t tell me much, no errors)) please ask!

I think a small prog to reproduce that can be made into a sample app 
would be a good idea.

-Andy

> Or am I expecting too much threading functionality?
>
> I’m halfway debugging, but kinda stuck :(
>
> Thanks!
> Bas
>
> On 20 Jun 2014, at 16:05, Mike M <andy.green at linaro.org
> <mailto:andy.green at linaro.org>> wrote:
>
>> Hi,
>>
>> After looking at the source for cancel, it appears that it uses data
>> from the internal structure.  So, it's not really safe to call it from
>> another thread.  If I want to make all this threadsafe, I need to lock
>> in the service thread before calling service, and also lock in the
>> other thread before I call cancel.  This will produce a deadlock
>> because service is waiting forever and already locked, so cancel will
>> never happen.
>>
>> -m
>>
>> On 06/20/2014 08:49 AM, Bas Appelo wrote:
>>> Ah, yes, I'm on the development version, I can recommend using it, it
>>> has some extra (badly needed as you discovered) functions, but I did
>>> not discover any drawback yet, I do consider it stable, I'm using it
>>> quite a lot:
>>>
>>> git clonegit://git.libwebsockets.org/libwebsockets
>>>
>>> Good luck!
>>>
>>> On 06/20/2014 02:39 PM, Mike M wrote:
>>>> Unfortunately, that call doesn't seem to exist in the version I'm
>>>> using.  What version is the latest stable version?
>>>>
>>>> Thanks!
>>>> -m
>>>>
>>>> On 06/20/2014 08:29 AM, Bas Appelo wrote:
>>>>> thread-1:
>>>>>     libwebsocket_service(context, LARGE_NUMBER); //blocks
>>>>>
>>>>> thread-2:
>>>>>     libwebsocket_cancel_service(context); // wakes up thread-1
>>>>>
>>>>> thread-1:
>>>>>     libwebsocket_callback_on_writable(context, wsi);
>>>>>     libwebsocket_service(context, LARGE_NUMBER); //blocks <= will
>>>>> call the callback!
>>>>>
>>>>> Now you will receive a callback, it works like a charm.
>>>>> So to write data you'll need to be in a callback, but the way above
>>>>> shows you how to get there/enforce one.
>>>>>
>>>>>
>>>>> On 06/20/2014 02:18 PM, Mike M wrote:
>>>>>> >>/  Hi,
>>>>>> />>/
>>>>>> />>/  1)Is there a way to asynchronously send the data to the client? That is,
>>>>>> />>/  without being in a callback, server spontaneously initiating data
>>>>>> />>/  transfer to the client..!!
>>>>>> />
>>>>>> >Libwebsockets is basically single-threaded.  But, with care from another
>>>>>> >server thread, you can call either
>>>>>> >
>>>>>> >libwebsocket_callback_on_writable(), or
>>>>>> >libwebsocket_callback_on_writable_all_protocol()
>>>>>> >
>>>>>> >but you need to manage your own list of live wsi / connections with the
>>>>>> >first option (by tracking their creating and destruction in the
>>>>>> >ESTABLISHED and CLOSED callbacks).
>>>>>> >
>>>>>> >You will get a LWS_CALLBACK_SERVER_WRITABLE as soon as it's possible to
>>>>>> >write on that connection then, and you should figure out what to write
>>>>>> >and write it from there.
>>>>>> >
>>>>>> >-Andy
>>>>>>
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> I am doing exactly this, but it doesn't work.
>>>>>>
>>>>>> I have a thread that calls libwebsocket_service with a huge
>>>>>> timeout. Writes, etc, are only ever done from within the
>>>>>> callback.  When I need to write something from another thread, I
>>>>>> queue up the message that needs to be written and then immediately
>>>>>> call libwebsocket_callback_on_writeable_all_protocol on the proto
>>>>>> I'm writing for.
>>>>>>
>>>>>> Unfortunately, I never get LWS_CALLBACK_SERVER_WRITEABLE until the
>>>>>> libwebsocket_service times out and gets called again.  This is
>>>>>> totally broken.  I saw a trac issue (#56) about using ppoll.
>>>>>> Unfortunately, the version of the library we're using doesn't seem
>>>>>> to have that code in it.  Any ideas?
>>>>>>
>>>>>> Thanks,
>>>>>> -m
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> Libwebsockets mailing list
>>>>>> Libwebsockets at ml.libwebsockets.org
>>>>>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Libwebsockets mailing list
>>>>> Libwebsockets at ml.libwebsockets.org
>>>>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Libwebsockets mailing list
>>>> Libwebsockets at ml.libwebsockets.org
>>>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>>
>>>
>>>
>>> _______________________________________________
>>> Libwebsockets mailing list
>>> Libwebsockets at ml.libwebsockets.org
>>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>
>> _______________________________________________
>> Libwebsockets mailing list
>> Libwebsockets at ml.libwebsockets.org
>> <mailto:Libwebsockets at ml.libwebsockets.org>
>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>
>
>
>
>
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>



More information about the Libwebsockets mailing list