someone
someone

Reputation: 13

Asp .net core SignalR send real time data

I have data and I want to present it to a user without him needing to refresh the page. I am using Asp .net core SignalR like this:

using System.Threading;
using Microsoft.AspNetCore.SignalR;
using WSEP212.DomainLayer;

namespace WebApplication.Publisher
{
    public class ChartNotifications : Hub
    {
        // Create the instance of ChartDataUpdate    
        // Send Data every 1 seconds    
        readonly int _updateInterval = 1000;       
        //Timer Class    
        private Timer _timer;    
        private volatile bool _sendingChartData = false;    
        private readonly object _chartUpateLock = new object();
        PieChart pieChart = new PieChart();
        
        public ChartNotifications() {}    
        
     
        public void InitChartData()    
        {
            //Show Chart initially when InitChartData called first time    
            pieChart.SetPieChartData();
            sendChartData(pieChart);
            //Call GetChartData to send Chart data every chosen interval
            GetChartData();
        }       
        
        public void GetChartData()    
        {
            _timer = new Timer(ChartTimerCallBack, null, _updateInterval, _updateInterval);
        }    
        private void ChartTimerCallBack(object state)    
        {
            if (_sendingChartData)    
            {    
                return;    
            }    
            lock (_chartUpateLock)    
            {    
                if (!_sendingChartData)    
                {    
                    _sendingChartData = true;
                    pieChart.SetPieChartData();
                    sendChartData(pieChart);    
                    _sendingChartData = false;    
                }    
            }
        }    
        
        public async void sendChartData(PieChart chart)
        {
           await Clients.All.SendAsync("updateChart", chart.GetPieChartData());
        }
    }
}

But I get an error -> System.ObjectDisposedException: Cannot access a disposed object. Object name: 'ChartNotifications'.

on the client side it looks like this:

chartConnection.start().then(() => {
            console.log("chart connection started");
            chartConnection.invoke('InitChartData');
});

Can you please tell me what I am doing wrong? or any other idea to use signalR to do this task? I new to this so please if you can elaborate on your answers.

Thank you in advance!!

Upvotes: 1

Views: 1425

Answers (1)

Knelis
Knelis

Reputation: 7129

This is not the recommended way to do this. The documentation explicitly says 'Hubs are transient' and 'Don't store state in a property on the hub class. Every hub method call is executed on a new hub instance.' So what you are trying to do, cannot be achieved this way.

What I would suggest you to do instead (no code provided, just some thoughts on architecture):

  1. Add a Hosted Service
  2. You can pass an IServiceProvider to the service constructor
  3. Let the service control a timer; when the timer elapses, you can use the service provider to create an IServiceScope and request an instance of IHubContext<ChartNotifications> (see documentation)
  4. Use that context to send updated data to connected clients

Upvotes: 1

Related Questions