[Libwebsockets] Forced disconnect for chocked connections

Andrejs Hanins andrejs.hanins at ubnt.com
Wed May 18 14:26:50 CEST 2016

On 05/18/2016 02:41 PM, Andy Green wrote:
> On 05/18/2016 07:20 PM, Andrejs Hanins wrote:
>> Andy,
>> On 05/18/2016 12:48 PM, Andy Green wrote:
>>> On 05/18/2016 05:37 PM, Andrejs Hanins wrote:
>>>> Hi,
>>>> As per documentation, one needs to enable TCP keep-alive to be
>>>> able to deal with chocked connection (not writable sockets), but
>>>> in my design there is a higher level timeouts which may request
>>>> to close a WS connection. Those close requests don't come from
>>>> the LWS callbacks, so I can't directly return -1 to LWS and need
>>>> to request writable callback which will never come if the
>>>> connection is chocked.
>>> Hum I think in other words it's suggesting "close from another
>>> thread" which can't fly.  But I do see the point.
>> No no. I have glib-based main loop and everything works in one
>> thread. So I want to close a WS connection from the same thread, but
>> not from the LWS callback. In my case this is asynchronous glib-timer
>> callback.
> How about just set a -1s timeout on the wsi then?
Oh, you mean just do lws_set_timeout for my wsi with negative delay so
that lws_service_timeout_check is called on next timeout servicing and
 do lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS) ?

If I understood it right, then it has exactly the effect I need - "close as a violent death
and don't try to do protocol cleanup like flush partials" :)

>>>> I'm thinking about some new API which will give a way to close a
>>>> socket from outside of the LWS callbacks despite any chocked
>>>> state.
>>>> Andy, others, do you think it could be a valuable improvement? I
>>>> don't really like that TCP keep-alive is the only way to deal
>>>> with chocked connections, especially when there are other higher
>>>> level timeouts implemented in use code.
>>> Yes I do think there's something to add here.
>>> But maybe it's about adding auto-PING/PONG timeouts on idle
>>> connections.  There's no point sending PINGs on active connections
>>> since to stay active, he has to be getting the remote ACKs.
>>> If a connection remains choked for a long time, in other words no
>>> TCP ACKs are coming, which implies no traffic is passing or the guy
>>> consuming the data is deadlocked, either way it's necessary he
>>> should be forcibly closed from the server side after a while.
>>> Lws timeouts (synchronously, within the service thread framework)
>>> can do the business end of that OK.
>>> Maybe what's needed is associate "send a ws PING if this connection
>>> has been idle for n sec" and "set an lws timeout when you send the
>>> PING" that is cleared by the PONG receipt.
>>> Because there are many "invisible" ills that might befall the
>>> remote peer or its interconnection that can't otherwise be
>>> determined.
>>> Will this solve your problem?
>> Well, auto-pinger in LWS would solve the problem with chocked
>> connections (my higher level code does exactly that - sends WS
>> PINGs), but it will not solve a more generic case when user code just
>> wants to unconditionally and immediately close the connection from
>> the same thread but not from the LWS callback. This might not be
>> related to timeouts at all.
> Still the auto PING is a missing piece (as proven by the fact you had to implement it on top of lws)
Yes, but I prefer to control it from my code by explicitly sending PINGs and waiting for PONGs, it is a
very easy thing to implement with any external message loop.

 You can still implement it for those who don't use external message loops, but I personally don't need
it anymore as soon as -1s timeout trick works.

Once again thank you for the super-sharp support Andy!
> -Andy
>>> -Andy
>>>> BR, Andrey _______________________________________________
>>>> Libwebsockets mailing list Libwebsockets at ml.libwebsockets.org
>>>> http://libwebsockets.org/mailman/listinfo/libwebsockets

More information about the Libwebsockets mailing list