[Libwebsockets] i->pwsi value returned to user in H2 pipeline case

Andy Green andy at warmcat.com
Thu Nov 15 23:27:51 CET 2018

On 16/11/2018 03:38, Xi Chen wrote:
> Thanks for the clarification, Andy.
> This is the problem I am facing:
> - I have multiple applications interacting with LWS main thread
> - When callback comes from LWS, I need to reroute them to corresponding 
> application (assuming application registers its callback to LWS)
> - Because of this, I need an exact mapping between application's i->pwsi 
> to wsi parameter in LWS callback(wsi, ...)
> - In current case, applicaiton 1 gets network wsi (while its LWS 
> callback uses stream wsi 1), and application 2 gets stream wsi 2
> How to deal with this case, any suggestion?

The wsi "user_space" member and related details from the original client 
connection wsi (which becomes the network wsi for h2 in this scenario) 
is also migrated to the generated wsi for h2 stream id 1, and removed 
from the network wsi.

In other words if you set struct lws_client_connect_info .userdata 
member when you create the client connections, binding your own data to 
the client connection, this is always coming back appropriately in the 
callback user parameter even in the h2 case where the first wsi has changed.

That's how it works in the minimal-client-http-multi example.


> On Wed, Nov 14, 2018 at 8:17 PM Andy Green <andy at warmcat.com 
> <mailto:andy at warmcat.com>> wrote:
>     On 15/11/2018 11:43, Xi Chen wrote:
>      > Hi Andy,
>      >
>      > I just want to understand the results I have with 2 children h2_wsi
>      > sharing the same network wsi.
>      >
>      > When I send the first request, it creates one network_wsi and
>     then one
>     The actual sequencing for the initial
>     lws_http_client_connect_via_info()
>     only goes as far as doing the name resolution and starting to make the
>     tcp connection with connect() on a nonblocking socket... it returns to
>     the caller without any error or conclusion at that time and i->pwsi is
>     set.  Later, after returning to the event loop, it will get POLLOUT
>     signalled on the socket to tell it retrying the connect() will now give
>     a result.
>     Until then, the client doesn't actually know if it will find an
>     h2-capable server or what, until after the connect() asynchronously
>     completes and tls ALPN information is coming back.
>      > h2_wsi (say wsi_1), however I notice that the application gets the
>      > i->pwsi value set to network_wsi instead of wsi_1. But later
>     callbacks
>      > such as HTTP_WRITE is called with wsi_1.
>     What happens there is the network wsi is wsi_1.  When it understands
>     from ALPN the server offers h2, lws goes down that road and the initial
>     client connection wsi becomes the h2 connection "network wsi" (after
>     all, that wsi already directly owns the socket).  A new wsi is created
>     to be the first stream wsi (SID 1), and the ah / client headers are
>     migrated from what is becoming the network wsi to the new stream wsi.
>     https://libwebsockets.org/git/libwebsockets/tree/lib/roles/h2/http2.c#n1221-1300
>     So the meaning of wsi_1 splits... the original wsi as a wrapper for the
>     socket stays the same and becomes the "network wsi" for the h2
>     connection.  The original wsi as a container for a client HTTP request
>     gets handed off to a newly created stream wsi attached as a child to
>     the
>     network wsi.
>     Also at that time any other queued client requests to the same host
>     that
>     had attached themselves to the first wsi are translated into h2 streams
>     to be serviced concurrently.
>      > When I send the second request with LCCSCF_PIPELINE  set, it
>     creates one
>      > h2_wsi (say wsi_2), and the application gets i->pwsi = wsi_2.
>      >
>      > Is this expected? I would expect the first application gets wsi_1
>     and
>      > the second application gets wsi_2 ...
>     That does happen, but wsi_1 gets split as described, since h2 doesn't
>     allow the network connection itself to have its own stream
>     content... it
>     has to create an explicit separate stream wsi with its own lifetime
>     as a
>     child of the network wsi.
>     -Andy
>      > Thanks
>      > -Xi
>      >
>      >
>      >
>      > _______________________________________________
>      > Libwebsockets mailing list
>      > Libwebsockets at ml.libwebsockets.org
>     <mailto:Libwebsockets at ml.libwebsockets.org>
>      > https://libwebsockets.org/mailman/listinfo/libwebsockets
>      >

More information about the Libwebsockets mailing list