OnDisconected not beein called, SignalR with slow Internet connections

Viewed 27

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:

FirstClient before the error

Second Client:

enter image description here

First Client after the error (after spam and get connection lost):

enter image description here

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!

0 Answers
Related