Как остановить таймер при 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 будет вызываться клиентами с некоторыми параметрами, основанными на параметрах, которые мне нужны для трансляции данных соответствующим клиентам.