<div dir="ltr"><div class="gmail_default" style="color:#3333ff">Thanks again Andy.</div><div class="gmail_default" style="color:#3333ff">I missed the secret flag :) Will give it a try.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Aug 22, 2018 at 2:15 PM, Andy Green <span dir="ltr"><<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
<br>
On 08/23/2018 02:38 AM, Xi Chen wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks for your reply Andy.<br>
<br>
I have a few comments:<br>
1. I quickly went thru the code (H2 client role specifically). For POLLIN, the h2n->swsi will be set by received stream id (sid), then corresponding h2 child wsi will be used.<br>
For POLLOUT, it seems doing a round-robin manner to go thru all child list of nwsi. Do I understand correctly?<br>
</blockquote>
<br></span>
That's right... the round-robin action is formed because when a child wsi gets some time and bandwidth on the shared nwsi, the child wsi is sent to the end of the sibling linked-list.  So he's last to be checked for wanting write access next time the nwsi is writable.<span class=""><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2. I have already went thru the minimum-http-client-multi example. However, from the debug log, I found that each client created its own socket (i.e., a nwsi and a child wsi). It seems the example creates multiple sockets rather than reusing the same socket. What I need is one nwsi (one socket) opened with multiple child wsi, each has its own sid value representing a different H2 stream. I do not see such API existing. Can you help confirm?<br>
<br>
To achieve this, seems I need to i) create new wsi; ii) add it in to nwsi's child list; iii) lws_h2_client_handshake(new wsi). Correct?<br>
</blockquote>
<br></span>
Yes, but... no, all this is already implemented and working.<br>
<br>
By default it acts as individual connections for backward compatibility.<br>
<br>
You need to use the flag LCCSCF_PIPELINE on the client connection info .ssl_connection to indicate you want either h1 pipelining or h2 broadsiding.<br>
<br>
<a href="https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/http-client/minimal-http-client-multi/minimal-http-client-multi.c#n236-238" rel="noreferrer" target="_blank">https://libwebsockets.org/git/<wbr>libwebsockets/tree/minimal-exa<wbr>mples/http-client/minimal-http<wbr>-client-multi/minimal-http-<wbr>client-multi.c#n236-238</a><br>
<br>
It is documented at the top of minimal-http-client-multi.c<br>
<br>
 * By default the connections happen all together at the beginning and operate<br>
 * concurrently, which is fast.  However this is resource-intenstive, there are<br>
 * 8 tcp connections, 8 tls tunnels on both the client and server.  You can<br>
 * instead opt to have the connections happen one after the other inside a<br>
 * single tcp connection and tls tunnel, using HTTP/1.1 pipelining.  To be<br>
 * eligible to be pipelined on another existing connection to the same server,<br>
 * the client connection must have the LCCSCF_PIPELINE flag on its<br>
 * info.ssl_connection member (this is independent of whether the connection<br>
 * is in ssl mode or not).<br>
 *<br>
 * HTTP/1.0: Pipelining only possible if Keep-Alive: yes sent by server<br>
 * HTTP/1.1: always possible... serializes requests<br>
 * HTTP/2:   always possible... all requests sent as individual streams in parallel<br>
<br>
and the flag has some documentation in libwebsockets.h<br>
<br>
        LCCSCF_PIPELINE                         = (1 << 16),<br>
                /**< Serialize / pipeline multiple client connections<br>
                 * on a single connection where possible.<br>
                 *<br>
                 * HTTP/1.0: possible if Keep-Alive: yes sent by server<br>
                 * HTTP/1.1: always possible... uses pipelining<br>
                 * HTTP/2:   always possible... uses parallel streams<br>
                 * */<br>
<br>
although I would agree it needs a document detailing all this new stuff in one place.<br>
<br>
If you give the -p flag to the -multi minimal example, adding LCCSCF_PIPELINE, you will see in debug stuff like this<br>
<br>
[2018/08/23 05:06:15:7180] INFO: lws_h2_dump_waiting_children: 0xe9b3e0: children waiting for POLLOUT service:<br>
[2018/08/23 05:06:15:7180] INFO:   * 0xea40a0 h2 http<br>
[2018/08/23 05:06:15:7180] INFO:   * 0xea5960 h2 http<br>
[2018/08/23 05:06:15:7180] INFO:   * 0xea7220 h2 http<br>
[2018/08/23 05:06:15:7180] INFO:   * 0xea8ae0 h2 http<br>
[2018/08/23 05:06:15:7180] INFO:   * 0xeaa3a0 h2 http<br>
[2018/08/23 05:06:15:7180] INFO:   * 0xeabc60 h2 http<br>
[2018/08/23 05:06:15:7180] INFO:   * 0xead520 h2 http<br>
[2018/08/23 05:06:15:7180] INFO:     0xebfba0 h2 http<br>
<br>
which is pretty clear that they are all using a single nwsi.<br>
<br>
-Andy<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks<br>
-Xi<div><div class="h5"><br>
<br>
On Tue, Aug 21, 2018 at 11:28 PM, Andy Green <<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a> <mailto:<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a>>> wrote:<br>
<br>
<br>
<br>
    On 08/21/2018 12:09 AM, Xi Chen wrote:<br>
<br>
        Hi,<br>
<br>
        I have two issues (maybe observations) which needs some<br>
        clarifications:<br>
<br>
          1.<br>
<br>
             Currently I send one H2 client request vis<br>
             lws_client_connect_via_info(), it creates one network wsi<br>
        (nwsi) and<br>
             then one h2 child wsi (h2_wsi). When I return -1 in the<br>
        callback, it<br>
             frees h2_wsi only. Why nwsi is not close?<br>
<br>
<br>
    (I must say I am gratified to hear someone talk about nwsi.  After<br>
    spending many months working on h2 support it's the first time<br>
    someone read the code AFAIK.)<br>
<br>
    It stays open for some time in case you have more client connections<br>
    to the same host coming.<br>
<br>
    Since v3.0 lws has a pretty sophisticated transparent queuing for<br>
    multi client connection to the same vhost, that works on http/1.1<br>
    pipelining if that's what you got or h2, broadsiding the connections<br>
    concurrently on a single TLS / tcp "nwsi".<br>
<br>
          2.<br>
<br>
             If I want to send the same request again, seems I need to call<br>
             lws_client_connect_via_info() again which creates nwsi and<br>
        h2_wsi<br>
             again (i.e., SSL handshake again), is there a way I can<br>
        reuse the<br>
             previous allocated nwsi and h2_wsi?<br>
<br>
<br>
    If the nwsi is still up, it should use it.<br>
<br>
    Have a play with:<br>
<br>
    <a href="https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/http-client/minimal-http-client-multi" rel="noreferrer" target="_blank">https://libwebsockets.org/git/<wbr>libwebsockets/tree/minimal-exa<wbr>mples/http-client/minimal-http<wbr>-client-multi</a><br>
    <<a href="https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/http-client/minimal-http-client-multi" rel="noreferrer" target="_blank">https://libwebsockets.org/git<wbr>/libwebsockets/tree/minimal-<wbr>examples/http-client/minimal-<wbr>http-client-multi</a>><br>
<br>
    this has switches that let you test multiple client connections<br>
    simultaneously or with with staggered delays (to stress the queuing<br>
    algorithm) in h1, h1 with pipelining and h2.  Various combinations<br>
    of this run as part of the CI testing on travis against both a local<br></div></div>
    server and <a href="http://libwebsockets.org" rel="noreferrer" target="_blank">libwebsockets.org</a> <<a href="http://libwebsockets.org" rel="noreferrer" target="_blank">http://libwebsockets.org</a>>.<span class=""><br>
<br>
    If there are problems coming, talking about how to reproduce them<br>
    with that + whatever hack patch is needed will make it much easier<br>
    to look at it.<br>
<br>
    -Andy<br>
<br>
        Thanks<br>
        -Xi<br>
<br>
<br>
<br>
<br>
        ______________________________<wbr>_________________<br>
        Libwebsockets mailing list<br>
        <a href="mailto:Libwebsockets@ml.libwebsockets.org" target="_blank">Libwebsockets@ml.libwebsockets<wbr>.org</a><br></span>
        <mailto:<a href="mailto:Libwebsockets@ml.libwebsockets.org" target="_blank">Libwebsockets@ml.libwe<wbr>bsockets.org</a>><br>
        <a href="https://libwebsockets.org/mailman/listinfo/libwebsockets" rel="noreferrer" target="_blank">https://libwebsockets.org/mail<wbr>man/listinfo/libwebsockets</a><br>
        <<a href="https://libwebsockets.org/mailman/listinfo/libwebsockets" rel="noreferrer" target="_blank">https://libwebsockets.org/mai<wbr>lman/listinfo/libwebsockets</a>><br>
<br>
<br>
</blockquote>
</blockquote></div><br></div>