[Libwebsockets] What is the proper way to keep stream connection?

Kun Zhao kunzhao77 at gmail.com
Mon Apr 29 02:37:50 CEST 2019


error C3861: 'lws_http_headers_detach': identifier not found

I am using 3.1-stable branch.

On Sun, Apr 28, 2019 at 7:31 PM Kun Zhao <kunzhao77 at gmail.com> wrote:

> Andy,
>
> Thanks for your reply. I'm trying to call the lws_http_headers_detach,
> but the function is not in the compiled header file (lws-http.h), did I
> miss something?
>
> Thanks,
> Kun
>
> On Sat, Apr 27, 2019 at 11:08 PM Andy Green <andy at warmcat.com> wrote:
>
>>
>>
>> On April 28, 2019 1:31:31 AM GMT+01:00, Kun Zhao <kunzhao77 at gmail.com>
>> wrote:
>> >Hi Andy,
>> >
>> >I have a HTTP client which receives data from a server. The connection
>> >is
>> >kept alive and the server sends data to the client periodically. The
>> >client
>> >receives data for a while then closed the connection. After some
>> >debugging,
>> >I found that the problem is here:
>> >
>> https://github.com/warmcat/libwebsockets/blob/2d2c0f0f9241fa449018baececdab83289b1e0f9/lib/core-net/service.c#L708
>> >
>> >the ah->assigned never updates and the session eventually timed out
>> >then
>> >and the client closed the connection.
>>
>> ah->assigned should never update... this code represents an lws policy
>> that user code must not hold onto an ah for a long period, the limit's like
>> 5 minutes.
>>
>> ah are 'detachable' heap-allocated structs that contain parsed http
>> headers... the're a few KB each but can be set larger at context creation
>> time; an ah pool can also be defined there based on how scarce memory is in
>> your system.  On h1, connections acquire an ah or go on a waiting list for
>> one before the request (server) or response (client) headers can be parsed.
>>
>> On h2, all the care about waiting lists and pools was turned on its
>> head... since h2 muxes control packets and an arbitrary number of http
>> streams on one connection, dealing with h2 means you cannot just defer
>> reading from the connection... you will deadlock being unable to send
>> anything because you deferred reading it to find the necessary tx credit
>> update control packets.  So if the h2 connection says it wants to open 10 x
>> http streams concurrently, which is pretty typical, lws must find or
>> allocate 10 x ah suddenly... we can't tolerate using the ah waiting list.
>>
>> For this reason ah are required to be freed ASAP and user code that keeps
>> them is regarded as a bug by lws.  For connections that upgrade to ws, this
>> is done by lws for you, the ah is detached just after ESTABLISHED is
>> called.  This is why if you care about the http headers on a ws connection,
>> you must query them at ESTABLISHED or keep copies of ones you care about at
>> that point.
>>
>> For long-lived http connections, you can detach the ah manually, again
>> after querying or copying critical info from it
>>
>>
>> https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-http.h#n700-708
>>
>> For h1 that and the wsi timeout is all lws needs you to do...
>> intermediaries or the remote server that understand h1 might enforce their
>> own idle timeouts though.  For h2 it's more complicated again... there are
>> two idle timeouts in play, one for a logical stream wsi, and one for the
>> 'nwsi' network wsi, the h2 socket connection that carries one or more
>> streams.  When you write something, both get 30s of life.  So if any stream
>> writes anything, the underlying nwsi keeps getting life.  If an individual
>> stream is idle, it will quickly get closed.
>>
>> With SSE and ws-over-h2, it introduced a concept of an 'immortal
>> stream'... an nwsi carrying at least one immortal stream is itself no
>> longer subject to timeouts.  This is to deliver the necessary ws semantics
>> over h2, where ws streams can idle forever by default.  This works ok vs
>> the ah assignation timeout because nwsi don't have an ah themselves, and
>> the upgraded-to-ws stream dropped their ah.
>>
>> Since you're already doing the keepalive stuff, it sounds like you just
>> need to drop the ah before entering your long wait.
>>
>> -Andy
>>
>> >What is the proper way to update the ah->assigned time stamp to keep
>> >the
>> >connection open?
>> >
>> >Following is the response header from the server.
>> >
>> >HTTP/1.1 200 OK
>> >Server: openresty/1.9.15.1
>> >Date: Sat, 27 Apr 2019 21:11:14 GMT
>> >Content-Type: application/octet-stream
>> >Transfer-Encoding: chunked
>> >Connection: close
>> >Access-Control-Allow-Headers: Authorization, Content-Type,
>> >Accept-Datetime-Format, OANDA-Agent, ETag
>> >Access-Control-Allow-Methods: PUT, PATCH, POST, GET, OPTIONS, DELETE
>> >Access-Control-Allow-Origin: *
>> >Access-Control-Expose-Headers: ETag, RequestID
>> >RequestID: 799161546957200243
>> >
>> >Following is the logs:
>> >[2019/04/27 19:05:01:8002] NOTICE: ah excessive hold: wsi
>> >00000000122CFC40
>> >  peer address: 198.105.26.108
>> >  ah pos 258
>> >[2019/04/27 19:05:01:8032] NOTICE:    connection: = close
>> >[2019/04/27 19:05:01:8042] NOTICE:    http/1.1  = 200 OK
>> >[2019/04/27 19:05:01:8052] NOTICE:    content-type: =
>> >application/octet-stream
>> >[2019/04/27 19:05:01:8072] NOTICE:    date: = Sat, 27 Apr 2019 23:56:03
>> >GMT
>> >[2019/04/27 19:05:01:8092] NOTICE:    access-control-allow-origin: = *
>> >[2019/04/27 19:05:01:8102] NOTICE:    server: = openresty/1.9.15.1
>> >[2019/04/27 19:05:01:8122] NOTICE:    transfer-encoding: = chunked
>> >[2019/04/27 19:05:01:8132] INFO: __lws_header_table_detach: wsi
>> >00000000122CFC40: ah 000000001230F9C0 (tsi=0, count = 1)
>> >[2019/04/27 19:05:01:8152] DEBUG: __lws_header_table_detach: wsi
>> >00000000122CFC40: ah held 544s, role/state 0x10000000 0x117,
>> >[2019/04/27 19:05:01:8182] INFO: __lws_header_table_detach: nobody
>> >usable
>> >waiting
>> >[2019/04/27 19:05:01:8202] INFO: _lws_destroy_ah: freed ah
>> >000000001230F9C0
>> >: pool length 0
>> >[2019/04/27 19:05:01:8222] INFO: __lws_header_table_detach: wsi
>> >00000000122CFC40: ah 000000001230F9C0 (tsi=0, count = 0)
>> >[2019/04/27 19:05:01:8242] INFO: __lws_close_free_wsi:
>> >00000000122CFC40:
>> >caller: excessive ah
>> >[2019/04/27 19:05:01:8262] DEBUG: __lws_close_free_wsi: real
>> >just_kill_connection: 00000000122CFC40 (sockfd 260)
>> >[2019/04/27 19:05:01:8282] DEBUG: __remove_wsi_socket_from_fds:
>> >wsi=00000000122CFC40, skt=260, fds pos=0, end guy pos=1, endfd=0
>> >[2019/04/27 19:05:01:8312] DEBUG: lwsi_set_state(00000000122CFC40,
>> >0x1000001e)
>> >
>> >Thanks,
>> >Kun Zhao
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20190428/2177483d/attachment-0001.htm>


More information about the Libwebsockets mailing list