First, I have ServiceStack as my server which provides RESTful HTTP API.
Here is an example.
public void GET(XXXXXRequest request)
{
System.Threading.Thread.Sleep(2000);
}
Then I use System.Net.Http.HttpClient
to access it.
As it is said here, HttpClient
is thread-safe for most of its methods to sending HTTP GET requests over the same TCP connection.
So I have a singleton instance of HttpClient as below
HttpClient _httpClient = new HttpClient(new WebRequestHandler()
{
AllowPipelining = true
});
Then I use the following test code to send the request one after previous's response
await _httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);
In smart sniffer, I do see the requests are sent in one connection and it goes like:
Client -> Request1
Client <- Response1
Client -> Request2
Client <- Response2
Client -> Request3
Client <- Response3
Now I change the code to fire-and-forget mode as below.
_httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);
So that the requests are sent without waiting for previous reponse and I expect the requests & response go like below
Client -> Request1
Client -> Request2
Client -> Request3
Client <- Response1
Client <- Response2
Client <- Response3
This is HTTP pipeline and quite good for performance.
But from my test, I see 3 connections are established for each of the HTTP GET request and it does not work as I expected.
Regarding the AllowPipelining
proeprty, MSDN says
An application uses the AllowPipelining property to indicate a preference for pipelined connections. When AllowPipelining is true, an application makes pipelined connections to the servers that support them.
So, I suppose HttpClient
does support pipelining, and the problem is located in ServiceStack? Is there some options in ServiceStack to enable HTTP pipelining?
Pipelining is done at a very low level, below IIS even (in the
http.sys
kernel mode driver). While I'm afraid I can't explain the behavior you're seeing, I can confidently say that ServiceStack is not on the hook for supporting it. It's an HttpHandler, whose only concern is how to process a request and return a response.