HttpClient将HTTP GET请求流水线化到ServiceStack API

Mr.*_*oor 6 http.sys servicestack dotnet-httpclient http-pipelining

首先,我有ServiceStack作为我的服务器,它提供RESTful HTTP API.

这是一个例子.

public void GET(XXXXXRequest request)
{
    System.Threading.Thread.Sleep(2000);
}
Run Code Online (Sandbox Code Playgroud)

然后我System.Net.Http.HttpClient用来访问它.正如这里所说的, HttpClient对于大多数方法来说,通过相同的TCP连接发送HTTP GET请求是线程安全的.

所以我有一个HttpClient的单例实例,如下所示

HttpClient _httpClient = new HttpClient(new WebRequestHandler()
{
    AllowPipelining = true
});
Run Code Online (Sandbox Code Playgroud)

然后我使用以下测试代码在上一次响应之后发送请求

await _httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);
Run Code Online (Sandbox Code Playgroud)

智能嗅探器中,我确实看到请求是通过一个连接发送的,它类似于:

Client -> Request1
Client <- Response1
Client -> Request2
Client <- Response2
Client -> Request3
Client <- Response3
Run Code Online (Sandbox Code Playgroud)

现在我将代码更改为fire-and-forget模式,如下所示.

_httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);
Run Code Online (Sandbox Code Playgroud)

这样就可以在不等待之前的响应的情况下发送请求,我希望请求和响应如下所示

Client -> Request1
Client -> Request2
Client -> Request3
Client <- Response1
Client <- Response2
Client <- Response3
Run Code Online (Sandbox Code Playgroud)

这是HTTP管道,非常适合性能.

在此输入图像描述

但是从我的测试中,我看到为每个HTTP GET请求建立了3个连接,并且它不能像我预期的那样工作.

关于这个AllowPipelining问题,MSDN

应用程序使用AllowPipelining属性指示管道连接的首选项.当AllowPipelining为true时,应用程序会与支持它们的服务器建立流水线连接.

所以,我认为HttpClient支持流水线操作,问题出在ServiceStack中?ServiceStack中是否有一些选项可以启用HTTP流水线操作?

Tod*_*ier 2

流水线是在非常低的级别完成的,甚至低于 IIS(在http.sys内核模式驱动程序中)。虽然我恐怕无法解释您所看到的行为,但我可以自信地说 ServiceStack 不会支持它。它是一个 HttpHandler,它唯一关心的是如何处理请求并返回响应。