Search code examples
c#.net-coresignalriis-8asp.net-core-signalr

SignalR dotnet 3.1 webapi hosted on IIS 8 (WebSocket enabled) works few minutes only


I am hosting a dotnet 3.1 WebApi with SignalR on IIS 8 with WebSocket Protocol enabled on the server. The hosted API application works just fine for the first few minutes but stops working after a while and doesn't respond to any requests.

Client-end is in Angular 11, which works as it should be. but when this happens, the client-side takes a long time to finish the API request.

And have to restart the application then again it works for few minutes.

IIS log shows this error

System.InvalidOperationException: The 'InvokeCoreAsync' method cannot be called if the connection is not active

Searched for this error but nothing is working till now.

Controller Constructure
/**
   Controller Constructure
**/
        private IDataTracker _iDataTracker;
        private HubConnection _signalRHubConnection;

        public DataTrackingController(IDataTracker iDataTracker){
            _iDataTracker = iDataTracker;
            if(_signalRHubConnection == null || _signalRHubConnection.State == HubConnectionState.Disconnected)
            {
                _signalRHubConnection = new HubConnectionBuilder()
                .WithUrl("http://locally-hosted-url/DataApi/dataHub")
                .WithAutomaticReconnect()
                .Build();
                _signalRHubConnection.StartAsync();
            }
        }
Controller Action
/**
  Controller Action
**/

[HttpPost]
public async Task<IActionResult> TrackDataAsync(DataModel dataObject){
      
      //database call
      var resultData = _iDataTracker.TrackData(dataObject);

      //SignalR Client call
      await _signalRHubConnection.InvokeAsync("SendData", dataObject);

      return Ok(resultData);
}
SignalR Hub

/**
  Hub class
**/

public class DataHub: Hub
    {
        public void SendData(DataModel dataObject)
        {
            Console.WriteLine("SignalR data: "+ dataObject.IQty);
            Clients.All.SendAsync("ReceiveData",dataObject);
        }

    }

Solution

  • Thanks, @lex-li for mentioning the issue with the controller instance. So now the Hub is instantiated with IHubContext and that apparently solved the issue here.

    /**
       Controller Constructure
    **/
            private IDataTracker _iDataTracker;
            private readonly IHubContext<ProductionCountHub> _hubContext;
    
            public DataTrackingController(IDataTracker iDataTracker,  
                                    IHubContext<ProductionCountHub> hubContext){
                _iDataTracker = iDataTracker;
                _hubContext = hubContext;
            }
    
    /**
      Controller Action
    **/
    
    [HttpPost]
    public async Task<IActionResult> TrackDataAsync(DataModel dataObject){
          
          //database call
          var resultData = _iDataTracker.TrackData(dataObject);
    
          //SignalR Client call
          await _hubContext.Clients.All.SendAsync("SendData", dataObject);
    
          return Ok(resultData);
    }