I used signalr with backend polling as a background service in my .NET web api project. However, when I try to connect to my hub from the client, it throws System.IO.IOExpcetion. I checked if web sockets are enabled on my IIS servers and they are. When I use long polling it works but when I try to use web sockets or SSE it gives 200 ok status but in case of web socket it waits for 101 upgrade request. In the second case with SSE it gives handshake error.
Thank you in advance.
This is the WebSocket Log
System.Net.WebSockets.WebSocketException (0x80004005): The server returned status code '200' when status code '101' was expected.
at System.Net.WebSockets.ClientWebSocket.ValidateResponse(HttpWebRequest request, HttpWebResponse response)
at System.Net.WebSockets.ClientWebSocket.<ConnectAsyncCore>d__21.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.<DefaultWebSocketFactory>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Http.Connections.Client.Internal.WebSocketsTransport.<StartAsync>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<StartTransport>d__47.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.<SelectAndStartTransport>d__44.MoveNext()
This is the SSE Log
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Debug: Starting receive loop.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Debug: Passing message to application. Payload size: 36.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Debug: Receive loop stopped.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Debug: Starting the send loop.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Debug: Send loop canceled.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Transport 'ServerSentEvents' started.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Debug: Send loop stopped.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Information: HttpConnection Started.
Microsoft.AspNetCore.SignalR.Client.HubConnection: Information: Using HubProtocol 'json v1'.
Microsoft.AspNetCore.SignalR.Client.HubConnection: Debug: Sending Hub Handshake.
Microsoft.AspNetCore.SignalR.Client.HubConnection: Error: The underlying connection closed while processing the handshake response. See exception for details.
System.IO.IOException: The server disconnected before the handshake could be started.
Microsoft.AspNetCore.SignalR.Client.HubConnection: Error: Error starting connection.
System.IO.IOException: The server disconnected before the handshake could be started.
at Microsoft.AspNetCore.SignalR.Client.HubConnection.<HandshakeAsync>d__89.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.<StartAsyncCore>d__62.MoveNext()
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Debug: Disposing HttpConnection.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Information: Transport is stopping.
Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport: Debug: Transport stopped.
Microsoft.AspNetCore.Http.Connections.Client.HttpConnection: Information: HttpConnection Disposed.
Exception thrown: 'System.IO.IOException' in mscorlib.dll
When i started client and backend project in my local it works perfeclty. I think the problem is in IIS configuration or firewall related but i controlled both of them and there is no blocking.
This is my client code:
string url = Hoppa.HoppaStatics.Endpoint + Endpoints.SignalR.ServiceHub;
_hubConnection = new HubConnectionBuilder()
.WithUrl(url, options =>
{
options.Transports = HttpTransportType.LongPolling;
})
.ConfigureLogging(logging =>
{
logging.AddDebug();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
})
.WithAutomaticReconnect()
.Build();
_hubConnection.On<UpdatesFromDbResponse>(Endpoints.SignalR.LastUpdate, (updates) =>
{
this.Invoke((MethodInvoker)(() =>
{
if (updates.FailedTransferCount > 0)
{
this.Parent.Text = $"{title} ({updates.FailedTransferCount})"; ;
this.hoppatab_Transfers.Text = $"{transferTitle} ({updates.FailedTransferCount})";
}
else
{
this.Parent.Text = title;
this.hoppatab_Transfers.Text = transferTitle;
}
if (updates.FailedMakerCheckerCount > 0)
{
this.hoppatab_MakerChecker.Text = $"{makerCheckerTitle} ({updates.FailedMakerCheckerCount})";
}
else
{
this.hoppatab_MakerChecker.Text = makerCheckerTitle;
}
}));
});
_hubConnection.On<int>(Endpoints.SignalR.HandShake, (control) =>
{
this.Invoke((MethodInvoker)(() =>
{
if (control == 0)
{
this.hoppatab_SystemData.Text = "Sistem Verileri";
}
else
{
this.hoppatab_SystemData.Text = $"Sistem Verileri ({control})";
}
}));
});
try
{
await _hubConnection.StartAsync();
Console.WriteLine("SignalR bağlantısı başarılı.");
}
catch (Exception ex)
{
MessageBox.Show("SignalR bağlantı hatası: " + ex.Message);
}
And this is the service configuration
var config = ConfigManager.Config();
if (config is not null && config.ServiceSettings is not null && config.ServiceSettings.BackendPollingMode)
endpoints.MapHub<ServicePrivateHub>(Constants.ServicePrivate.ApiBase + "serviceprivatehub");