0

I'm trying to push notifications to clients who have connected to SignalR Hub based on related events are happening in Asterisk PBX VOIP server using AsterNet ARI.

I can get events using DeviceStateChangedEvent class from AsterNet using an event handler and want to push notification to clients related to their devices' state changes.

Also, SignalR connection is working as well and welcome message is showing on client web page.

But the problem is while sending notification by SendAsync method to caller client, my Hub goes to be disposed and below exception raised:

System.ObjectDisposedException: 'Cannot access a disposed object. Object name: 'AgentHub'.'

Here is my Hub class which I've overridden the OnConnectedAsync() method to send welcome message and put event handler for listening events from PBX.

    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();

        }
    }
4

1 回答 1

0

集线器是短暂的,它们仅在执行集线器方法时存在。这里发生的是您正在为捕获“this”(集线器)的 OnDeviceStateChangedEvent 创建一个事件。稍后触发事件时,您将尝试访问该方法退出后立即释放的 Hub。

为了正确执行此操作,您需要注入IHubContext<AgentHub>Hub 的构造函数,然后将其存储Context.ConnectionId在您的事件中。

并且不要Context.ConnectionId直接在您的活动中使用,因为这将捕获“this”并具有相同的问题。相反,您可以在集线器方法内部的事件外部创建一个变量,以在事件内部存储Context.ConnectionId和使用该变量。

于 2020-01-24T22:06:54.840 回答