Signal R connection state is 0 after sometime

Viewed 862

I am using @aspnet/signalr to connect to a hub and from the hub i am calling the method to return me some data.

When i first initialize the server the connection is established normally, but if i refresh the window 3 or 4 times the client stop sending connection request to the server.

I tried logging the HubConnection, the connectionState at first is equal to 1 but after the problem accrues the connectionState is alwase equal 0

Here is how i am building the hubConnection:

buildConnection() {
this.hubConnection = new HubConnectionBuilder()
.withUrl(this.tradesService.getStockQuotationsHubUrl())
.build();
this.hubConnection.serverTimeoutInMilliseconds = 1000 * 10;
this.hubConnection.onclose(() => setTimeout(() => this.startSignalRConnection(), 2000));}

Here is how i am starting the hubConnection:

startConnection() {
    this.hubConnection
      .start()
      .then(() => {
      this.hubConnection.on('updateMethod', (data: any) => {
        
          this.store.push([
            { type: 'update', key: data.stockID, data },
          ]);
         
        });
      this.dataSource = new DataSource({
          store: this.store,
          reshapeOnPush: true,
        });
      });}

Note: I am listing to 5 hubs at once in my page but the only one having problems is this one.

[Update]

The problem is from the server because when i restart the server the connection is reestablished between the client and the server, but if the client refresh or quit the page for multiple times the hub does not even try to connect to the client

public class StockQuotationsHub : Microsoft.AspNetCore.SignalR.Hub
  {
    private string SectorID { get; set; }
    private int TradingSession { get; set; }
    private int MarketID { get; set; }

public static StockQuotationExt stockQuotationExt { get; set; }
private readonly StockQuotationTicker _stockTicker;

public StockQuotationsHub(StockQuotationTicker stockTicker){
    _stockTicker = stockTicker;
}

public override Task OnConnectedAsync(){
return base.OnConnectedAsync();
}

public IEnumerable<StockQuotation> GetAllStockQuotations(string[] stockID, string sectorID, int tradingSession, int marketType){
    return _stockTicker.
    GetAllStocks(Context.ConnectionId, stockID, sectorID, tradingSession, marketType);
        }

public override async Task OnDisconnectedAsync(Exception exception){
    await base.OnDisconnectedAsync(exception);
}

and here is my stock ticker class:

public IEnumerable<StockQuotation> GetAllStocks(string connectionId, string[] stockID, string sectorID, int tradingSession, int marketType)
    {
        _stocks = new List<StockQuotation>();
        _stocks = Task.Run(async () => await GetStockQuotationModelAsync("", 0, 1, 0)).Result.ToList();
        this.MaxTimeStamp = _stocks.Max(s => s.TStamp);
        this.SectorID = sectorID;
        this.TradingSession = tradingSession;
        this.MarketID = marketType;

        AddToGroups(connectionId, stockID);

        if (_timer==null)
            _timer = new Timer(UpdateStockPrices, null, _updateInterval, _updateInterval);

        if (stockID.Length == 0)
        {
            return _stocks;
        }
        else
        {
            var stocksList = new List<StockQuotation>();
            foreach (var stock in stockID)
            {
                stocksList.AddRange(_stocks.Where(s => s.StockID == stock).ToList());
            }
            return stocksList;
        }
    }

private void AddToGroups(string connectionId, string[] stockID)
        {
            if (_stocks.Count > 0)
            {
                if (stockID.Length == 0)
                {
                    Hub.Groups.AddToGroupAsync(connectionId, "ALL");
                }
                else
                {
                    foreach (var stock in stockID)
                    {
                        Hub.Groups.AddToGroupAsync(connectionId, stock);
                        var s = _stocks.FirstOrDefault(s => s.StockID == stock);
                        if(s != null)
                        {
                        s.Snapshots = new List<double>(GetStockQuotationSnapshots(stock));
                        }
                    }
                }
            }
        }
private void AddToGroups(string connectionId, string[] stockID)
        {
            if (_stocks.Count > 0)
            {
                if (stockID.Length == 0)
                {
                    Hub.Groups.AddToGroupAsync(connectionId, "ALL");
                }
                else
                {
                    foreach (var stock in stockID)
                    {
                        Hub.Groups.AddToGroupAsync(connectionId, stock);
                        var s = _stocks.FirstOrDefault(s => s.StockID == stock);
                        if(s != null)
                        {
                        s.Snapshots = new List<double>(GetStockQuotationSnapshots(stock));
                        }
                    }
                }
            }
        }

I really appreciated the help.

2 Answers

Eventually the problem was that the project type was MVC, so I changed it to be webApi and everything worked successfully

Even if you fix it I would like to recommend you to add the following code in order to know exactly the root cause of disconnection.

First of all enable the extended debug info in the service configuration:

services.AddSignalR(o =>
            {
                o.EnableDetailedErrors = true;
            });

Furthermore, you need to attach to the event Closed in HubConnection like that:

hubConnection.Closed += (exception) =>
            {
                if (exception == null)
                {
                    Console.WriteLine("Connection closed without error.");
                }
                else
                {
                    Console.WriteLine($"Connection closed due to an error: {exception}");
                }
                return null;
            };
Related