【发布时间】:2020-04-27 10:36:04
【问题描述】:
我在后台服务中使用 .NET SignalR 客户端(SignalR Core 2.2 和 DotNet Core 2.2)。在我的循环中,我检查我的连接对象是否已断开连接,如果是,则触发 ConnectAsync。
我正在尝试使用 SignalR 进行高可用性故障转移检测(以及其他事情,例如配置同步),因此有关远程主机关闭或变得不可用的时间至关重要。
我遇到的问题是,在 Linux 上,超时似乎没有正确响应。虽然我将所有可配置的超时设置为以秒为单位的非常短的激进时间,但在 Linux 上运行时需要几分钟才能超时。 Windows 似乎没有同样的问题。
if (_connection.State != HubConnectionState.Connected) {
_connection = new HubConnectionBuilder()
.ConfigureLogging(logging => {
logging.SetMinimumLevel(LogLevel.Information);
logging.AddConsole();
})
.WithUrl("https://" + settings.RemoteIP + ":" + settings.RemotePort + "/api/hub/ha", options => {
options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets | Microsoft.AspNetCore.Http.Connections.HttpTransportType.ServerSentEvents;
options.AccessTokenProvider = () => Task.FromResult(settings.RemoteJWT);
options.CloseTimeout = new TimeSpan(0, 0, 8);
})
.Build();
_connection.HandshakeTimeout = new TimeSpan(0, 0, 5);
_connection.ServerTimeout = new TimeSpan(0, 0, 10);
_connection.KeepAliveInterval = new TimeSpan(0, 0, 5);
_connection.On("ExampleEvent", async () =>
{
await ExampleProcessor(_logger, cancellation);
});
await _connection.StartAsync(cancellation);
}
在尝试连接到不可用的服务器后正好 120 秒后,我收到以下超时错误:
System.OperationCanceledException: The operation was canceled. at
System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts) at
System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.NegotiateAsync(Uri url, HttpClient httpClient, ILogger logger) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.GetNegotiationResponseAsync(Uri uri) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.SelectAndStartTransport(TransferFormat transferFormat) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsyncCore(TransferFormat transferFormat) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(TransferFormat transferFormat, CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory.ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory.ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken)
在 Windows 上,超时需要 21 秒,但出现不同的错误:
System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) --- End of inner exception stack trace --- at
System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) at
System.Threading.Tasks.ValueTask`1.get_Result() at
System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask`1.get_Result() at
System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask) at System.Threading.Tasks.ValueTask`1.get_Result() at
System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at
Microsoft.AspNetCore.Http.Connections.Client.Internal.AccessTokenHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Connections.Client.Internal.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at
System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.NegotiateAsync(Uri url, HttpClient httpClient, ILogger logger) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.GetNegotiationResponseAsync(Uri uri) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.SelectAndStartTransport(TransferFormat transferFormat) at
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsyncCore(TransferFormat transferFormat) at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(TransferFormat transferFormat, CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory.ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HttpConnectionFactory.ConnectAsync(TransferFormat transferFormat, CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken) at
Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken)
我没有正确设置超时吗?还是 DotNet Core SignalR 2.2 存在潜在问题?
【问题讨论】:
-
你的意思是你为连接设置了server timeout interval,当客户端应用在Linux上运行时,它不能正常工作?
-
我不确定要为初始 ConnectAsync() 寻找哪个超时设置;如果远程服务器关闭并且我调用 ConnectAsync(),我希望它在几秒钟内超时,而不是几分钟。如果那是 ServerTimeout 设置,那么是的,它的行为不像预期的那样,真的是在 windows 或 linux 上 - linux 更糟糕。我不确定 Negotiate 超时不是初始超时,也不知道 CloseTimeout 的用途。
-
这不是一个答案,但我只是想提一下 .NET Core 2.2 在December 23, 2019 已终止生命周期。您可能需要考虑更新到 Core 3.1,看看您的问题在该设置中是否仍然存在。
标签: c# asp.net-core .net-core signalr.client asp.net-core-signalr