如何使用signalR c#MVC接收特定于用户的消息?

如何使用signalR c#MVC接收特定于用户的消息?,c#,asp.net-mvc,signalr,signalr.client,C#,Asp.net Mvc,Signalr,Signalr.client,我有一个MVC应用程序 我已经实现了singalR来接收实时通知,但是如何只获取特定于用户的通知 NotificationSend.cs public class NotificationSend : Hub { private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationSend>(); public static ConcurrentD

我有一个MVC应用程序

我已经实现了singalR来接收实时通知,但是如何只获取特定于用户的通知

NotificationSend.cs

public class NotificationSend : Hub
{
    private static IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<NotificationSend>();
    public static ConcurrentDictionary<string, MyUserType> MyUsers = new ConcurrentDictionary<string, MyUserType>();

    public override Task OnConnected()
    {
        MyUsers.TryAdd(Context.ConnectionId, new MyUserType() { ConnectionId = Context.ConnectionId });
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        MyUserType garbage;

        MyUsers.TryRemove(Context.ConnectionId, out garbage);

        return base.OnDisconnected(stopCalled);
    }

    public static void SendToUser(string messageText)
    {
        hubContext.Clients.Client(MyUsers.Keys.ToList().FirstOrDefault()).Notification(messageText);
    }

    public static void StopLoader(string messageText)
    {
        hubContext.Clients.Client(MyUsers.Keys.ToList().FirstOrDefault()).Stoploader(messageText);
    }
}
public class MyUserType
{
    public string ConnectionId { get; set; }
}
Layout.js

$(function () {
            var notification = $.connection.notificationSend;
            console.log(notification);
            notification.client.Notification = function (Count) {
                $('#liveupdate').empty();
                $('#liveupdate').show();
                $('#liveupdate').append(Count);
            };
            $.connection.hub.start().done(function () {
                var connectionId = $.connection.hub.id;
                console.log("Connected Successfully");
            }).fail(function (response) {
                console.log("not connected" + response);
            });
        });

下面是我在VB.Net中的示例代码(您可以将其转换为C#):

你必须使用组。基本上我所做的是一组是为一个用户。通过用户名定义

然后只需调用函数:

Dim user As User = idb.Users.Where(Function(a) a.id = userid).FirstOrDefault
Dim msg as string = "Any notification message"
SignalRHub.SendToUser(user.UserName, msg)
最后,使用javascript代码触发:

var notification = $.connection.signalRHub;
notification.client.addNewMessageToPage = function (msg) {
    $("#notification").prepend(msg);
}

ID通知,您要将通知消息放在哪里。

这是我在VB.Net中的示例代码(您可以将其转换为C):

你必须使用组。基本上我所做的是一组是为一个用户。通过用户名定义

然后只需调用函数:

Dim user As User = idb.Users.Where(Function(a) a.id = userid).FirstOrDefault
Dim msg as string = "Any notification message"
SignalRHub.SendToUser(user.UserName, msg)
最后,使用javascript代码触发:

var notification = $.connection.signalRHub;
notification.client.addNewMessageToPage = function (msg) {
    $("#notification").prepend(msg);
}

ID通知,您要将通知消息放在其中。

添加一个静态类,它的实例将被创建一次,并将信息像上下文实例一样保留在内存中

public static class NotificationsResourceHandler
{
    private static readonly IHubContext myContext;       
    public static Dictionary<string, string> Groups;



    static NotificationsResourceHandler()
    {
        myContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();   
        Groups = new Dictionary<string, string>();
    }

    public static void BroadcastNotification(dynamic model, NotificationType notificationType, string userName)
    {
        myContext.Clients.Group(userName).PushNotification(new { Data = model, Type = notificationType.ToString() });
    }
}

通知将被推送到各个组,对于您的问题,您应该按照代码中的规定为每个用户创建一个单独的组。

添加一个静态类。它的实例将被创建一次,并将信息保存在内存中,如上下文实例

public static class NotificationsResourceHandler
{
    private static readonly IHubContext myContext;       
    public static Dictionary<string, string> Groups;



    static NotificationsResourceHandler()
    {
        myContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();   
        Groups = new Dictionary<string, string>();
    }

    public static void BroadcastNotification(dynamic model, NotificationType notificationType, string userName)
    {
        myContext.Clients.Group(userName).PushNotification(new { Data = model, Type = notificationType.ToString() });
    }
}

通知将被推送到各个组,对于您的问题,您应该按照代码中提供的方式为每个用户创建一个单独的组。

对于要发送回客户端的消息,服务器需要知道套接字连接信息,并且通过使用相同的浏览器实例,我认为结果地址是相同的,这就是为什么会将消息推送到所有选项卡,SignalR工作正常您在
SignalR
中向哪些用户注册?这一行做什么呢
hubContext.Clients.All.Notification(mydata.Name+“:数据已保存”)
您是否实现了
OnConnected()
OnDisconnected()
在您的
Hub
中?首先,在内存中创建一个静态类来persist
HubContext
实例,并根据用户的id或电子邮件向Hub添加一个组,该组可以唯一地识别他/她,然后使用上下文将通知推送到仅包含该用户的特定组。我已添加了我的答案,看看这是否对发送回客户端的消息有意义服务器需要知道套接字连接信息,并且通过使用相同的浏览器实例,生成的地址是相同的,我认为,这就是消息被推送到所有选项卡的原因,信号器工作正常。您在
signer
中向各个用户注册了什么?这一行做什么呢
hubContext.Clients.All.Notification(mydata.Name+“:数据已保存”)
您是否实现了
OnConnected()
OnDisconnected()
在您的
Hub
中?首先,在内存中创建一个静态类来persist
HubContext
实例,并根据用户的id或电子邮件向Hub添加一个组,该组可以唯一地识别他/她,然后使用上下文将通知推送到仅包含该用户的特定组。我已添加了我的答案,看看这是不是让senseI尝试过但没有收到通知:(你能帮我使用c#代码吗?该代码适用于特定用户登录,其他用户不应该希望看到其他通知。我尝试过但没有收到通知:(你能帮我使用c#代码吗?该代码适用于特定的用户登录,其他用户不希望看到其他通知。谢谢你的努力,但我现在可以更改完整的实现,如果有机会我们可以更改我当前的代码吗?我可以试试,我有这个解决方案,这就是我发布它的原因,我可以尝试给你r代码正常工作,同时,您可以设置此解决方案并保留前一个解决方案,如果可行,然后使用此解决方案转换您的解决方案。感谢您的努力,但我现在可以更改完整的实现,我们是否有可能更改我当前的代码?我可以尝试,我有此解决方案为我工作,这就是我发布此解决方案的原因,我可以尝试让您的代码正常工作,同时,您可以设置此解决方案并保留前一个解决方案(如果可行),然后使用此解决方案转换您的代码。
[HubName("yourHub")]
public class MyHub : Hub
{
    public override Task OnConnected()
    {
        var userEmail = Context.QueryString["useremail"]?.ToLower();
        if (userEmail == null) throw new Exception("Unable to Connect to Signalr hub");

        if (NotificationsResourceHandler.Groups.All(x => x.Value != userEmail))
        {
            NotificationsResourceHandler.Groups.Add(Context.ConnectionId, userEmail);
            Groups.Add(Context.ConnectionId, userEmail);
        }
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        NotificationsResourceHandler.Groups.Remove(Context.ConnectionId);
        Clients.All.removeConnection(Context.ConnectionId);

        return base.OnDisconnected(stopCalled);
    }
}