SignalR TimeOutException 每 30 秒发生一次

Ben*_*en5 6 c# websocket signalr asp.net-core blazor

我们使用 Blazor 和 SignalR 在客户端和服务器之间创建 Websocket 连接。在所有系统上,我们看到每 30 秒就会有一个错误记录到控制台:

This_console_error:7 失败:Microsoft.AspNetCore.SignalR.Client.HubConnection[69] HubConnection 由于错误而重新连接。System.TimeoutException:服务器超时(30000.00ms)已过,但没有收到来自服务器的消息。_bound_js_globalThis_console_err

我们在客户端设置连接,如下所示:

HubConnection hubConnection = new HubConnectionBuilder()
                .WithUrl(navigationManager.ToAbsoluteUri(HubConstants.TransportPackages),
                options => {
                    options.AccessTokenProvider = () => Task.FromResult(authenticationService?.User?.Token);
                    options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets | Microsoft.AspNetCore.Http.Connections.HttpTransportType.ServerSentEvents | Microsoft.AspNetCore.Http.Connections.HttpTransportType.LongPolling;

                })
                .ConfigureLogging(logging => {
                    logging.AddProvider(loggerProvider);
                })
                .WithAutomaticReconnect()
                .Build();

            hubConnection.On(HubConstants.ReceiveTransportPackage, handler);

            await hubConnection.StartAsync();
Run Code Online (Sandbox Code Playgroud)

如果我们删除“.WithAutomaticReconnect()”,则错误消息会有所不同:

失败:Microsoft.AspNetCore.SignalR.Client.HubConnection[12] 连接由于错误而关闭。System.TimeoutException:服务器超时(30000.00ms)已过,但没有收到来自服务器的消息。

看起来由于超时设置(在服务器上?)而记录了错误。但为什么会被记录为错误呢?这是设计使然还是我们做错了什么?

我们知道,如果我们删除“logging.AddProvider(loggerProvider);” 该错误将不再被记录,但我们仍然希望有其他日志消息。

Ben*_*en5 7

我已经找到问题了。问题是服务器的配置如下:

var signalRService = services.AddSignalR(o =>
                {
                    o.KeepAliveInterval = TimeSpan.FromSeconds(60);  
                });
Run Code Online (Sandbox Code Playgroud)

默认情况下,客户端上的 HubConnection.ServerTimeout 设置为 30。将服务器上的 KeepAliveInterval 设置为 15 秒(这实际上是默认值)后,它现在就像一个没有错误日志和重新连接的魅力一样。

所以由于服务器上的KeepAliveInterval高于客户端上配置的ServerTimeout,所以总是出现超时,连接异常关闭。由于在我们的应用程序中,客户端仅接收,但从不发送,因此连接永远不会保持足够长的活动时间。由于我们使用的是自动重新连接,它最终仍然有效。但这并不理想,并导致大量重新连接和日志消息。