Уведомление SignalR, Pu sh подключенным клиентам в зависимости от происходящего события позволяет утилизировать концентратор - PullRequest
0 голосов
/ 24 января 2020

Я пытаюсь отправить sh уведомления клиентам, которые подключились к SignalR Hub на основе связанных событий, происходящих в Asterisk УАТС VOIP-сервер с использованием Aste rNet ARI .

Я могу получать события, используя класс DeviceStateChangedEvent из Aste rNet, используя обработчик событий, и хочу отправлять sh уведомления клиентам, связанные с изменениями состояния их устройств.

Кроме того, SignalR Соединение также работает, и на веб-странице клиента отображается приветственное сообщение.

Но проблема заключается в том, что при отправке уведомления вызывающим клиентом методом SendAsyn c мой концентратор удаляется и возникает исключение:

System.ObjectDisposedException: 'Невозможно получить доступ к удаленному объекту. Имя объекта: 'AgentHub'. '

Вот мой класс-концентратор, в котором я переопределил метод OnConnectedAsyn c () для отправки приветственного сообщения и установки обработчика событий для прослушивания событий из УАТС.

    public class AgentHub : Hub
    {
        public static AriClient ActionClient;

        public override async Task OnConnectedAsync()
        {
            ActionClient = new AriClient(
               new StasisEndpoint("voipserver", port, "username", "password"),
               "HelloWorld",
               true);

            ActionClient.Connect();

            ActionClient.OnDeviceStateChangedEvent += new DeviceStateChangedEventHandler(async delegate (IAriClient sender, DeviceStateChangedEvent e)
            {
                var notification = new DeviceStateChangeNotification
                {
                    NotificationText = e.Device_state.Name + "'s state changed to " + e.Device_state.State,
                    SentAt = DateTime.Now.ToString()
                };

                await Clients.Caller.SendAsync(
                    "ReceiveNotification",
                    notification.NotificationText,
                    notification.SentAt
                );
            });

            var notification = new DeviceStateChangeNotification
            {
                NotificationText = "Welcome!",
                SentAt = DateTime.Now.ToString()
            };

            await Clients.Caller.SendAsync(
                "ReceiveNotification",
                notification.NotificationText,
                notification.SentAt
            );

            await base.OnConnectedAsync();

        }
    }

1 Ответ

0 голосов
/ 25 января 2020

Концентраторы недолговечны, они существуют только во время выполнения метода концентратора. Здесь происходит то, что вы создаете событие для OnDeviceStateChangedEvent, которое захватывает «this» (концентратор). Позже, когда событие инициируется, вы пытаетесь получить доступ к концентратору, который был удален сразу после выхода из метода.

Для правильного выполнения этого вам необходимо добавить IHubContext<AgentHub> в конструктор концентратора. а затем сохраните это и Context.ConnectionId в вашем событии.

И не используйте Context.ConnectionId непосредственно в вашем событии, потому что это уловит «это» и вызовет ту же проблему. Вместо этого вы можете создать переменную вне события внутри метода-концентратора для хранения Context.ConnectionId и использовать эту переменную внутри события.

...