在Azure中部署后,Asp.net SignalR无法正常运行

时间:2019-02-01 12:44:03

标签: asp.net-mvc signalr signalr-hub azure-redis-cache signalr-backplane

我正在使用Asp.Net信号发送用户特定的通知。使用Visual Studio在调试模式下一切正常,但在部署到Azure时会中断。

我正在使用Redis缓存。

Startup.cs

using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(NotifSystem.Web.Startup))]
namespace NotifSystem.Web
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            GlobalHost.DependencyResolver.UseStackExchangeRedis(new RedisScaleoutConfiguration("mySrver:6380,password=password,ssl=True", "YourServer"));
            app.MapSignalR();
        }
    }
}

我的中心班级:

using Microsoft.AspNet.SignalR;
using NotificationHub.Models.Hubs;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace NotificationHub.Hubs
{
    public class NotificationHub : Hub
    {
        private static readonly ConcurrentDictionary<string, UserHubModels> Users =
            new ConcurrentDictionary<string, UserHubModels>(StringComparer.InvariantCultureIgnoreCase);

        //private NotifEntities context = new NotifEntities();

    //Logged Use Call
    public void GetNotification()
    {
        try
        {
            string loggedUser = Context.User.Identity.Name;

            //Get TotalNotification
            //string totalNotif = LoadNotifData(loggedUser);

            //Send To
            UserHubModels receiver;
            if (Users.TryGetValue(loggedUser, out receiver))
            {
                var cid = receiver.ConnectionIds.FirstOrDefault();
                var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
                context.Clients.Client(cid).broadcaastNotif();
            }
        }
        catch (Exception ex)
        {
            ex.ToString();
        }
    }

    //Specific User Call
    public void SendNotification(string SentTo,string Notification)
    {
        try
        {
            //Get TotalNotification
            //string totalNotif = LoadNotifData(SentTo);

            //Send To
            UserHubModels receiver;
            if (Users.TryGetValue(SentTo, out receiver))
            {
                var cid = receiver.ConnectionIds.FirstOrDefault();
                var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
                context.Clients.Client(cid).broadcaastNotif(Notification);
            }
        }
        catch (Exception ex)
        {
            ex.ToString();
        }
    }

    private string LoadNotifData(string userId)
    {
        return userId;
        int total = 0;
        //var query = (from t in context.Notifications
        //             where t.SentTo == userId
        //             select t)
        //            .ToList();
        total = 6;
        return total.ToString();
    }

    public override Task OnConnected()
    {

        string userName = Context.User.Identity.Name;
        string connectionId = Context.ConnectionId;

        var user = Users.GetOrAdd(userName, _ => new UserHubModels
        {
            UserName = userName,
            ConnectionIds = new HashSet<string>()
        });

        lock (user.ConnectionIds)
        {
            user.ConnectionIds.Add(connectionId);
            if (user.ConnectionIds.Count == 1)
            {
                Clients.Others.userConnected(userName);
            }
        }

        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        string userName = Context.User.Identity.Name;
        string connectionId = Context.ConnectionId;

        UserHubModels user;
        Users.TryGetValue(userName, out user);

        if (user != null)
        {
            lock (user.ConnectionIds)
            {
                user.ConnectionIds.RemoveWhere(cid => cid.Equals(connectionId));
                if (!user.ConnectionIds.Any())
                {
                    UserHubModels removedUser;
                    Users.TryRemove(userName, out removedUser);
                    Clients.Others.userDisconnected(userName);
                }
            }
        }

        return base.OnDisconnected(stopCalled);
    }
}

}

JavaScript代码:

var hub = $.connection.notificationHub;
hub.client.broadcaastNotif = function (notification) {
    setTotalNotification(notification)
};
$.connection.hub.start()
    .done(function () {
        console.log("Connected!");
        hub.server.getNotification();
    })
    .fail(function () {
        console.log("Could not Connect!");
    }); 
 });

function setTotalNotification(notification) {
    if (notification) {
        GetUnreadNotificationCount();
        $('#m_topbar_notification_icon .m-nav__link-icon').addClass('m-animate-shake');
        $('#m_topbar_notification_icon .m-nav__link-badge').addClass('m-animate-blink');
    }
    else {
        $('#m_topbar_notification_icon .m-nav__link-icon').removeClass('m-animate-shake');
        $('#m_topbar_notification_icon .m-nav__link-badge').removeClass('m-animate-blink');
    }
}

我已为该特定的应用程序服务启用了Websocket。

跨用户通知发送失败,仅当登录的用户仅向自己发送通知时,它才有效。

更新:

我检查了一个登录用户正在执行的活动时,该通知会发送给该特定用户,然后它才能正常工作。就像用户user1user1发送通知一样,就没有问题。

1 个答案:

答案 0 :(得分:1)

我们的 Azure SignalR redis BackPlane POC同样存在问题

但是我们尝试使用没有SSL端口的Redis,然后Azure SignalR redis BackPlane开始正常工作。请检查以下屏幕截图。现在,由于环境是独立的,我们甚至不需要HTTPS。我们通过资源组和端口白名单对其进行管理。

enter image description here