King Fisher Ответов: 0

Как остановить таймер при ondisconnected событии в signalr


Я запустил таймер, когда мое соединение с концентратором устанавливается в методе PushNotificationData по запросам клиентов.

В соответствии с интервалом таймера он действительно извлекает записи из БД и отправляет их клиентам. но когда клиенты отключаются, этот таймер должен быть остановлен вместо того, чтобы тянуть непрерывно.

Поэтому я использовал событие OnDisconnected, чтобы остановить таймер. но, к сожалению таймер не становится остановился

public class NotifyHub : Hub
    {
        private string ConnectionId;
        private int UserId;
        private int UserTypeId;

        Timer timer = new Timer();

        public override Task OnConnected()
        {
            ConnectionId = Context.ConnectionId;
            return base.OnConnected();
        }
        public override Task OnDisconnected(bool stopCalled)
        {
            timer.Stop();
            timer.Enabled = false;
            //logic code removed for brevity
            return base.OnDisconnected(stopCalled);
        }
        public void PushNotificationData(Int32 userId, Int16 userTypeId)
        {

            UserId = userId;
            UserTypeId = userTypeId;
            ConnectionId = Context.ConnectionId;

            timer.Elapsed += Timer_Elapsed1;
            timer.Interval = 6000;
            timer.Enabled = true;
            timer.Start();

        }
    private void Timer_Elapsed1(object sender, ElapsedEventArgs e)
        {
            var notificationParams = new PushNotificationRequest
            {
                FilterProperty = new Common.Filters.FilterProperty { Offset = 0, RecordLimit = 0, OrderBy = "datechecked desc" },
                Filters = new List<Common.Filters.FilterObject> { new Common.Filters.FilterObject { LogicOperator = 0, ConditionOperator = 0, Function = 0, FieldName = "", FieldValue = "", FieldType = 0 } }
            };
            using (INotificationManager iNotifity = new NotificationManager())
            {
                var taskTimer = Task.Run(async () =>
                {                        
                        var NotificationResult = iNotifity.GetPushNotificationData(notificationParams, UserId, UserTypeId);
                        //Sending the response data to all the clients based on ConnectionId through the client method NotificationToClient()
                        Clients.Client(ConnectionId).NotificationToClient(NotificationResult);
                        //Delaying by 6 seconds.
                        await Task.Delay(1000);
                        //}
                  });
            }
        }  
    }


Что я уже пробовал:

public override Task OnDisconnected(bool stopCalled)
       {
           timer.Stop();
           timer.Enabled = false;
           //logic code removed for brevity
           return base.OnDisconnected(stopCalled);
       }


When I debug it, it shows timer enabled=true even after OnDisconnected fires.


Обновление: вместо таймера я написал, как показано ниже. из-за этого цикла у меня возникла проблема с производительностью на сервере.

public void PushNotificationData(Int32 userId, Int16 userTypeId)
        {
            UserId = userId;
            UserTypeId = userTypeId;
            ConnectionId = Context.ConnectionId;
            //timer = new Timer();
            //timer.Elapsed += Timer_Elapsed1;
            //timer.Interval = 6000;
            //timer.Enabled = true;
            //timer.Start();

            lock (this)
            {
                var notificationParams = new PushNotificationRequest
                {
                    FilterProperty = new Common.Filters.FilterProperty { Offset = 0, RecordLimit = 0, OrderBy = "datechecked desc" },
                    Filters = new List<Common.Filters.FilterObject> { new Common.Filters.FilterObject { LogicOperator = 0, ConditionOperator = 0, Function = 0, FieldName = "", FieldValue = "", FieldType = 0 } }
                };
                using (INotificationManager iNotifity = new NotificationManager())
                {
                    var taskTimer = Task.Run(async () =>
                    {
                        while (true)
                        {
                            var NotificationResult = iNotifity.GetPushNotificationData(notificationParams, UserId, UserTypeId);
                            //Sending the response data to all the clients based on ConnectionId through the client method NotificationToClient()
                            Clients.Client(ConnectionId).NotificationToClient(NotificationResult);
                            //Delaying by 6 seconds.
                            await Task.Delay(6000);
                        }
                    });
                }
            }
        }

Andy Lanng

эээ... вы... но... aaahhhg - столько ошибок!

Концентратор является или, по крайней мере, должен быть одиночка Таким образом, вы не можете создать таймер для каждого соединения.

Не зная больше о вашей системе, я предлагаю вам держать таймер включенным и постоянно транслировать то, что вам нужно. Не выключайте таймер для всех только потому, что один человек отключился.

Это также означает, что вы должны запустить таймер в конструкторе, а не когда кто-то подключается. Так лежит боль

King Fisher

Как создать таймер для каждого соединения ?

Andy Lanng

Ваш интервал таймера составляет 6 секунд. Нет никакого смысла создавать 1 на соединение, потому что они будут постоянно стрелять. Просто имейте 1 таймер, который вещает всем, кто случайно подключен.

King Fisher

пожалуйста, проверьте обновления в разделе" Что я пробовал:".

Из-за этого цикла у меня возникла проблема с производительностью на сервере, поэтому мы внезапно вернули коды обратно. И то, что вы предлагаете, тоже похоже, верно ?

Andy Lanng

да, в значительной степени. Я бы так не поступил, но не вижу в этом никаких проблем: ~)

King Fisher

но у нас возникли проблемы с производительностью на сервере, и мы внезапно вернули код с живого сервера.

King Fisher

но каждый запрос на соединение будет циклическим и выполняться как отдельный экземпляр, верно ? Если я не остановлю цикл, он никогда не закончится, и экземпляр увеличится как огромный, верно ?

Andy Lanng

Запустите цикл или таймер в конструкторе концентратора. Он запустится один раз (потому что ваш хаб должен быть одноэлементным) и не остановится. Подумайте об этом предполагаемом поведении. Я бы лично выбрал таймер, но это не должно иметь значения.

Концентратор сохраняет каждое соединение при подключении и удаляет их при отключении. Если вы вещаете клиентам.Клиенты, то только подключенные клиенты получают получить событие, потому что все остальные соединения не существуют: Þ

King Fisher

Всякий раз, когда пользователь подключается, метод PushNotificationData будет вызываться клиентами с некоторыми параметрами, основанными на параметрах, которые мне нужны для трансляции данных соответствующим клиентам.

0 Ответов