2

As far as I know, in HTTP 1.1 you can use the same TCP/IP connection for multiple requests, but you can't execute more than one request at a time on that connection. In other words, it has to go like: Request, Response, Request, Response, Request, .... You can't do something like: Req1, Req2, Resp1, Req3, Resp3, Resp2. Maybe you can with HTTP/2, I don't know.

Anyway, my question is: what happens if you try to send multiple simultaneous requests with FlurlClient?

Like:

    using (var client = new FlurlClient("https://api.com"))
    {
        var req1Task = client.Request("path1").PostJsonAsync(thing);
        var req2Task = client.Request("path2").GetAsync();

         await Task.WhenAll(req1Task, req2Task);
         // Do something with responses.
    }

I know the answer for HttpClient.

The answer is that if you try to start another request on HttpClient when a request is already pending, HttpClient will create a new TCP/IP connection. Whereas if you had waited until the first request was done, HttpClient would reuse the connection for the 2nd request.

My guess is that FlurlClient is the same.

N73k
  • 527
  • 8
  • 20
  • I'm not an expert on the protocols but I do know HTTP 1.1 supports [pipelining](https://en.wikipedia.org/wiki/HTTP_pipelining), so I'm not sure your assumption about one request at a time is accurate. – Todd Menier Aug 15 '18 at 00:50
  • This comment is about HttpClient (not FlurlClient) which would be the same anyway. When I run the above example with this: var client = new HttpClient(new WebRequestHandler() { AllowPipelining = true })), then .NET (or somewhere in Windows) still makes multiple connections. I don't know whose fault that is - the client or the server. – N73k Aug 15 '18 at 02:30
  • Anyway, I don't really agree with multiplexing multiple simultaneous HTTP requests/responses on the same TCP connection. That's what multiple TCP connections are for. That kind of complexity should be handled at a lower level. And we should not run out of ports at 65535. – N73k Aug 15 '18 at 02:33

1 Answers1

3

Your assumption is correct about FlurlClient behaving the same as HttpClient in that regard. Flurl is just a thin abstraction layer on top of HttpClient, which is itself an abstraction on top of several more layers. Eventually you hit the platform-specific networking stack that actually implements the protocols.

It is valid and (usually) smart to have multiple calls happening concurrently like you've done in your example. Once connection limits are hit (which is adjustable via ServicePointManager), requests will simply queue up until a connection is available. Just be sure that number doesn't get too high or you'll likely start receiving errors from the server. Also, like HttpClient, be sure you're reusing a FlurlClient instance as much as possible so you don't run into this problem.

Todd Menier
  • 37,557
  • 17
  • 150
  • 173