[Libwebsockets] Segfault

"Andy Green (林安廸)" andy at warmcat.com
Tue Jan 29 12:44:23 CET 2013


On 29/01/13 19:31, the mail apparently from Jack Mitchell included:
> On 29/01/13 11:20, "Andy Green (林安廸)" wrote:
>> On 29/01/13 19:12, the mail apparently from Jack Mitchell included:
>>>
>>>> No worries, I am wondering if the broadcast and forked service stuff
>>>> is leading people down the wrong path at the moment and should get
>>>> removed, so it will be interesting to see how you go.
>>>>
>>>> -Andy
>>>
>>> Sorry to snip this short but I couldn't cope with all the indentation.
>>>
>>> I have now implemented a ring buffer but something odd is happening.
>>> With 1 page open it performs fine, however when I open an additional
>>> page only some of the data makes it through the socket? I check for a
>>
>> It seems that when you send data to one websocket client, you mark it
>> at that time "done" from your ringbuffer?  Actually it's only
>> "consumed" when you sent it to everybody who cares.
>>
>> -Andy
>
> Should libwebsocket_callback_on_writable_all_protocol() not give me a
> callback with a wsi that writes to all the clients of that protocol as I

Sort of...

> did with broadcast()? Or am I missing something fundamental, where I
> need to loop over each wsi and write them individually somehow?

No you don't hae to do anything extra about that.

The point is that different connections may become writeable at grossly 
different rates.  Consider one guy is connecting through a 3G phone, his 
connection may disappear and reappear over several seconds.  He's not 
going to become writeable (and get that callback with his wsi) while 
he's in a tunnel or whatever and you already filled his pipe; he's not 
emptying his pipe at that time.  It sounds like you're thinking of these 
connections as perfect data sinks and they are not at all.

Instead what that call is doing is promising to give you a call back for 
each wsi of that protocol "when they can take some more".  So for the 
tunnel guy, his callback will come when he has come out of the tunnel 
and received and acknowledged the first packet in his pipe.  Other 
connections to other peers will of course have been chugging along 
taking data the whole time.

So, you need a policy for how long you will buffer content in your 
ringbuffer before the remote client won't "catch up" any more if it 
stopped receiving for a while, and you need to only retire ringbuffer 
entries that have gone to all consumers you are willing to send to.

The approach the test server takes is when the ringbuffer has filled up, 
to free up the entry that would be overwritten by the next incoming one.

-Andy

>>> choked socket in my LWS_CALLBACK_SERVER_WRITEABLE case but it never
>>> flags so I don't think it is a choked socket. Do you have any ideas?
>>>
>>> So the first page continues to work as expected, the second page only
>>> receives snippets of data. My code is similar to the following:
>>>
>>> Polling loop:
>>>
>>> while (1)
>>>      {
>>>
>>>          usleep(50000);
>>>
>>>          libwebsocket_service(websocketContext, 0);
>>>
>>>           if (!ringBuffer_isEmpty(buff)
>>>          {
>>>
>>>          libwebsocket_callback_on_writable_all_protocol(
>>>             webSocketProtocol[PROTOCOL_SEND_RECIEVE]);
>>>
>>>          }
>>>      }
>>>
>>> LWS_CALLBACK
>>>
>>>        case LWS_CALLBACK_SERVER_WRITEABLE:
>>>
>>>           do {
>>>
>>>              if (lws_send_pipe_choked(wsi))
>>>              {
>>>
>>>                 printf("Pipe was choked, giving it some breathing
>>> space!\n");
>>>                 break;
>>>
>>>              }
>>>
>>>              allConsumed = ringBuffer_consume(psd_sr->buff, jsonString);
>>>
>>>              n = sprintf((char*)p, "%s", jsonString);
>>>
>>>              n = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT);
>>>
>>>              if (n < 0)
>>>              {
>>>
>>>                 handleError(DB_ERR_SOCKET,"Failed to write to socket!
>>> (LWS_CALLBACK_SERVER_WRITEABLE)", __FUNCTION__);
>>>                 return 1;
>>>
>>>              }
>>>
>>>           } while ( allConsumed != 1 );
>>>
>>>           break;
>>>
>>> Cheers,
>>>
>>
>
>




More information about the Libwebsockets mailing list