首先,我将ServiceStack作为我的服务器,提供RESTful HTTP API。
这是一个例子。
mvn
然后我使用public void GET(XXXXXRequest request)
{
System.Threading.Thread.Sleep(2000);
}
来访问它。
正如here所述,System.Net.Http.HttpClient
对于大多数方法来说都是线程安全的,可以通过同一个TCP连接发送HTTP GET请求。
所以我有一个HttpClient的单例实例,如下所示
HttpClient
然后我使用以下测试代码在之前的响应
之后发送请求HttpClient _httpClient = new HttpClient(new WebRequestHandler()
{
AllowPipelining = true
});
在smart sniffer中,我确实看到请求是通过一个连接发送的,它类似于:
await _httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);
现在我将代码更改为fire-and-forget模式,如下所示。
Client -> Request1
Client <- Response1
Client -> Request2
Client <- Response2
Client -> Request3
Client <- Response3
这样就可以在不等待之前的响应的情况下发送请求,并且期望请求&amp;响应如下
_httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);
这是HTTP pipeline,非常适合表现。
但是从我的测试中,我看到每个HTTP GET请求都建立了3个连接,但它不能像我预期的那样工作。
关于Client -> Request1
Client -> Request2
Client -> Request3
Client <- Response1
Client <- Response2
Client <- Response3
proeprty,MSDN说
应用程序使用AllowPipelining属性来指示 对流水线连接的偏好。当AllowPipelining为true时,a 应用程序与支持的服务器建立流水线连接 它们。
所以,我认为AllowPipelining
确实支持流水线操作,问题出在ServiceStack中? ServiceStack中是否有一些选项可以启用HTTP流水线操作?
答案 0 :(得分:2)
流水线操作在非常低的级别完成,甚至低于IIS(在http.sys
内核模式驱动程序中)。虽然我担心我无法解释你所看到的行为,但我可以自信地说ServiceStack并没有支持它。它是一个HttpHandler,它唯一关心的是如何处理请求并返回响应。
答案 1 :(得分:0)
当您使用多个await
运算符时,它们会一个接一个地运行,因此HttpClient一次只能获得一个请求,因此无法使用流水线操作。
您可以使用Task.WhenAll()并行运行多个任务:
var responses = await Task.WhenAll(
_httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead),
_httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead),
_httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead));
var response1 = responses[0];
var response2 = responses[1];
var response3 = responses[2];
请注意,只等待Task.WhenAll