asp.net-mvc - Asp.net SignalR 在 Azure 中部署时无法工作

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

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

我正在使用redis缓存。

启动.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();
        }
    }
}

我的中心类(class):

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 发送通知一样,就没有问题。

最佳答案

我们的 Azure SignalR redis BackPlane POC 也遇到了同样的问题。

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

enter image description here

关于asp.net-mvc - Asp.net SignalR 在 Azure 中部署时无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54479799/

相关文章:

asp.net-mvc - 更改 SignalR Core 中的全局设置配置

signalr - 启动时调用 SignalR 客户端方法

asp.net-mvc - 解决防伪 token 问题

asp.net-mvc - 跟踪登录用户

asp.net - Session 在 MVC 中实际上是如何工作的?

SignalR持久连接在回显/协商中给出404

SignalR - 发送到多个客户端(不是一组)

asp.net-mvc-3 - Controller 内的 SignalR 身份验证?

.net - 在 UWP 中连接到 SignalR(核心)集线器时获取 "The certificate authority is invalid or incorrect"

javascript - 无法将表单数据发布到 Controller