超过 2 分钟的 gRPC 流调用被客户端和服务器之间的硬件(路由器等)终止
gRPC streaming call which takes longer than 2 minutes is killed by hardware (routers, etc.) in between client and server
Grpc.Net 客户:
- gRpc 客户端向 gRpc 服务器发送大量数据
- gRpc服务器收到客户端的数据后,http2通道变为空闲(但打开),直到服务器returns响应给客户端
- gRpc 服务器收到数据并开始处理它。如果数据处理时间超过 2 分钟(这是 http 调用的默认空闲超时),则响应永远不会到达客户端,因为通道实际上已断开连接,但客户端不知道这一点,因为它在其间被其他硬件关闭由于空闲时间长。
解决方案:
- 当在 gRpc 客户端创建通道时,它必须设置一个 httpClient
- httpClient 必须从 socketsHttpHandler 实例化
以下属性集(PooledConnectionIdleTimeout、PooledConnectionLifetime、KeepAlivePingPolicy、KeepAlivePingTimeout、KeepAlivePingDelay)
代码被截断:
SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler()
{
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(180),
PooledConnectionLifetime = TimeSpan.FromMinutes(180),
KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always,
KeepAlivePingTimeout = TimeSpan.FromSeconds(90),
KeepAlivePingDelay = TimeSpan.FromSeconds(90)
};
socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient httpClient = new HttpClient(socketsHttpHandler);
httpClient.Timeout = TimeSpan.FromMinutes(180);
var channel = GrpcChannel.ForAddress(_agentServerURL, new GrpcChannelOptions
{
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials),
MaxReceiveMessageSize = null,
MaxSendMessageSize = null,
MaxRetryAttempts = null,
MaxRetryBufferPerCallSize = null,
MaxRetryBufferSize = null,
HttpClient = httpClient
});
这就是我需要的。这个问题我几个月了,但我唯一的解决办法是减少数据量。
Grpc.Net 客户:
- gRpc 客户端向 gRpc 服务器发送大量数据
- gRpc服务器收到客户端的数据后,http2通道变为空闲(但打开),直到服务器returns响应给客户端
- gRpc 服务器收到数据并开始处理它。如果数据处理时间超过 2 分钟(这是 http 调用的默认空闲超时),则响应永远不会到达客户端,因为通道实际上已断开连接,但客户端不知道这一点,因为它在其间被其他硬件关闭由于空闲时间长。
解决方案:
- 当在 gRpc 客户端创建通道时,它必须设置一个 httpClient
- httpClient 必须从 socketsHttpHandler 实例化 以下属性集(PooledConnectionIdleTimeout、PooledConnectionLifetime、KeepAlivePingPolicy、KeepAlivePingTimeout、KeepAlivePingDelay)
代码被截断:
SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler()
{
PooledConnectionIdleTimeout = TimeSpan.FromMinutes(180),
PooledConnectionLifetime = TimeSpan.FromMinutes(180),
KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always,
KeepAlivePingTimeout = TimeSpan.FromSeconds(90),
KeepAlivePingDelay = TimeSpan.FromSeconds(90)
};
socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient httpClient = new HttpClient(socketsHttpHandler);
httpClient.Timeout = TimeSpan.FromMinutes(180);
var channel = GrpcChannel.ForAddress(_agentServerURL, new GrpcChannelOptions
{
Credentials = ChannelCredentials.Create(new SslCredentials(), credentials),
MaxReceiveMessageSize = null,
MaxSendMessageSize = null,
MaxRetryAttempts = null,
MaxRetryBufferPerCallSize = null,
MaxRetryBufferSize = null,
HttpClient = httpClient
});
这就是我需要的。这个问题我几个月了,但我唯一的解决办法是减少数据量。