SignalR TimeOutException every 30 seconds
Asked Answered
P

1

7

We are using Blazor and SignalR to create a websocket connection between the client and our server. On all systems we see that every 30 seconds an error is logged to the console:

This_console_error:7 fail: Microsoft.AspNetCore.SignalR.Client.HubConnection[69] HubConnection reconnecting due to an error. System.TimeoutException: Server timeout (30000.00ms) elapsed without receiving a message from the server. _bound_js_globalThis_console_err

We are setting up the connection on the client side like this:

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();

if we remove ".WithAutomaticReconnect()" then the error message is different:

fail: Microsoft.AspNetCore.SignalR.Client.HubConnection[12] Connection is shutting down due to an error. System.TimeoutException: Server timeout (30000.00ms) elapsed without receiving a message from the server.

It looks like the error is logged because of the timeout setting (on the server?). But why is it logged as an error? Is this by design or are we doing something wrong?

We know that if we remove "logging.AddProvider(loggerProvider);" the error will not be logged anymore, but we still want to have other logs messages.

Perchloride answered 31/5, 2023 at 8:15 Comment(2)
Default disconnect timeout is 30 seconds. Change this in your server side.Doering
And what is the right timeout? Since our application might not send / receive a message for several hours. We never want this error to be logged.Perchloride
P
10

I have found the issue. The problem was that the server was configured like this:

var signalRService = services.AddSignalR(o =>
                {
                    o.KeepAliveInterval = TimeSpan.FromSeconds(60);  
                });

And by default on the client the HubConnection.ServerTimeout is set to 30. After setting KeepAliveInterval on the server to 15 seconds (Which is actually the default) it now works like a charm without error logs and reconnects.

So since the KeepAliveInterval on the server was higher than the ServerTimeout configured on the client, there was always a timeout and the connection was closed with an exception. Since in our application the client was only receiving, but never sending, the connection was never kept alive long enough. It still worked in the end since we are using automatic reconnect. But this was not ideal and caused a lot of reconnects and log messages.

Perchloride answered 31/5, 2023 at 9:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.