I'm new using SignalR and I got stuck with a issue in OnDisconect event.
My project is kind of a cinema seats picker, that a user can select a seat and make a order.
When the user select the seat make it unavailable, in my front-end seat button send a post to my API that register de data of the seat and the ConnectionId of the user, and I use that connection Id when the user disconect (OnDisconectAsync in my API) without pay to make my seat available again.
The problem that I found was when a user has a Slow 3G connection, and spam checking and unchecking de reservation button, the SignalR connection get slow enought to throw this error:
"Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled."
And then "disconect" the user without calling OnDisconectAsyn() on my API and generating a new ConnectionId to my user.
So now if the user close de window the seats never comes back because the older ConnectionId got lost.
OnDisconect Method:
public override async Task OnDisconnectedAsync(Exception exception)
{
IOrderApplication order = scope.ServiceProvider.GetRequiredService<IOrderApplication>();
List<ViewOrderDto> orderList = await order.DeleteByConnectionId(Context.ConnectionId);
foreach (ViewOrderDto order in orderList)
{
await SendMessage(order);
}
await base.OnDisconnectedAsync(exception);
}
Controller Post:
[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] PostOrderDto postOrderDto)
{
if (!ModelState.IsValid)
return CustomResponseFail(ModelState);
if (string.IsNullOrEmpty(postOrderDto.ConnectionId))
{
NotifyError("ConnectionId can not be null.");
return CustomResponseFail(ModelState);
}
ViewOrderDto order = await rderApplication.PostAsync(postOrderDto);
if (order is null)
{
NotifyError("Error when making a order.");
return CustomResponseFail(ModelState);
}
await messageHub.SendMessage(order);
// await pedidoBackgroundService.UpdateOrders();
return CustomResponseSuccess(order, "Succeded order!");
}
First Client Before the Error:
Second Client:
First Client after the error (after spam and get connection lost):
I don't know if there is a better way to make this, or a way to solve this problem but i'm really thankfull for all the help!


