SignalR推送通知与MVC4特定客户端 [英] SignalR push-notification to specific client with MVC4

查看:202
本文介绍了SignalR推送通知与MVC4特定客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用SignalR与MVC4 C#项目推送通知发送到只选定的客户端。
对于这个我使用'context.Clients.Client在C#中的静态变量存储Context.ConnectionId'{因为无法与signalr使用会话}。
但是,由于contextConnectionId'是一个静态变量;文仍然boardcasted到所有客户端:(

有没有替代的会话与信号或任何其他优雅的方式做到这一点? (发现一些相关的文章,但没有具体的答案)

code如下:

的javaScript

  $(文件)。就绪(函数(){
 {
    VAR聊天= $ .connection.PushNotify;
    chat.client.addNewMessageToPage =功能(类型,消息){
        如果(类型==东西)
        {
            警报(消息);
        }
    }
    //开始连接。
    $ .connection.hub.start()。完成(功能(){
        chat.server.send($('')VAL(),$('')VAL());
    });
 )}

在C#HUB

  [HubName(PushNotify)]
公共类PushNotify:集线器
{
    公共无效发送(字符串名称,字符串消息)
    {
        //承担其C#静态变量
        GlobalVariable.contextConnectionId = Context.ConnectionId;
    }
}
公共类PushNotification
{
    公共无效SendMessage函数(字符串消息,字符串类型=味精)
    {
        如果(!string.IsNullOrEmpty(GlobalVariable.contextConnectionId))
        {
            VAR背景= GlobalHost.ConnectionManager.GetHubContext< PushNotify>();
            context.Clients.Client(GlobalVariable.contextConnectionId).addNewMessageToPage(类型,消息);
        }    }
}


解决方案

我不认为你预期示例将工作。当你映射到静态变量的连接你实际上覆盖你的静态变量,要求发送方法的最后一个连接。


  

连接到集线器的每个客户端传递一个唯一的连接ID。您可以
  在轮毂的Context.ConnectionId属性检索此值
  上下文。


这意味着你的 GlobalVariable.contextConnectionId 不能是简单的字符串。你有你的客户的方式映射,并且每个客户端都将有一个唯一的连接ID。也许是一本字典就足够了这里,或包含更多信息的类。 (即浏览器的信息,IP adderss ...)

(报价从这个链接)这会帮助你:的http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections

修改

提供了更多的信息:

我相信你的问题最简单的解决方法是使用群体。 http://www.asp.net/signalr /概述/引导到了-API /工作与 - 群体

您枢纽类将包含一个方法来加入组:

 公共任务JoinGroup(串组名)
{
    返回Groups.Add(Context.ConnectionId,组名);
}公共任务LeaveGroup(串组名)
{
    返回Groups.Remove(Context.ConnectionId,组名);
}

和我们说一个PostMessage的哪个发送到只有一个给定的组群:

 公共无效的SendMessage(串组名,字符串消息,字符串类型=味精)
{
    VAR背景= GlobalHost.ConnectionManager.GetHubContext< PushNotify>();
    context.Clients.Group(组名).addNewMessageToPage(类型,消息);
}

当你的客户加入,他们可以连接到一个组,其他一切由SignalR进行处理。

从客户和发布消息加盟本集团:

  VAR聊天= $ .connection.PushNotify;
$ .connection.hub.start()。完成(功能(){
    chat.server.joinGroup(组1);
    chat.server.sendMessage(组1,你好);
});

接收消息是一样的。

  chat.client.addNewMessageToPage =功能(类型,消息){
   ...
}

其他的解决办法

另一种解决办法是使用自己的映射或SignalR连接映射。这些解决方案需要覆盖OnConnected和OnDisconnected方法和映射您的连接。即:

 私人只读静态ConnectionMapping<串GT; _connections =
        新ConnectionMapping<串GT;();公众覆盖任务OnConnected()
{
    字符串名称= Context.User.Identity.Name;
    _connections.Add(姓名,Context.ConnectionId);
    返回base.OnConnected();
}公众覆盖任务OnDisconnected(布尔stopCalled)
{
    字符串名称= Context.User.Identity.Name;
    _connections.Remove(姓名,Context.ConnectionId);
    返回base.OnDisconnected(stopCalled);
}公共无效SendChatMessage(字符串谁,字符串消息)
{
    字符串名称= Context.User.Identity.Name;
    的foreach(在_connections.GetConnections VAR的ConnectionId(谁))
    {
        Clients.Client(的ConnectionId).addChatMessage(名称+:+消息);
    }
}

就像这个例子:的http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections#inmemory

I am trying to use SignalR with MVC4 c# project to send push notification to selected clients only. For this I am using 'context.Clients.Client' by storing 'Context.ConnectionId' in c# static variable {since unable to use session with signalr}. But since 'contextConnectionId' is a static variable; the message is still boardcasted to all clients :(

Is there any alternative to session with signal or any other elegant way to do this? (found few related post but no specific answers)

Code as below:

javaScript

 $(document).ready(function (){
 {
    var chat = $.connection.PushNotify;
    chat.client.addNewMessageToPage = function (type, message) {
        if(type == "something")
        {
            alert(message);
        }
    }
    // Start the connection.
    $.connection.hub.start().done(function () {
        chat.server.send($('').val(), $('').val());
    });
 )}

In c# HUB

[HubName("PushNotify")]
public class PushNotify : Hub
{
    public void Send(string name, string message)
    {
        //assume its c# static variable
        GlobalVariable.contextConnectionId = Context.ConnectionId;
    }
}
public class PushNotification
{
    public void SendMessage(string message, string type = "msg")
    {
        if (!string.IsNullOrEmpty(GlobalVariable.contextConnectionId))
        {
            var context = GlobalHost.ConnectionManager.GetHubContext<PushNotify>();
            context.Clients.Client(GlobalVariable.contextConnectionId).addNewMessageToPage(type, message);
        }

    }
}

解决方案

I don't think you example will work as expected. When you map your connection to your static variable you actually overwrite your static variable to the last connection which called Send method.

Each client connecting to a hub passes a unique connection id. You can retrieve this value in the Context.ConnectionId property of the hub context.

Which means your GlobalVariable.contextConnectionId cannot be a simple string. You have to map your clients in a way, and every client is going to have a unique connection id. Perhaps a dictionary would be enough here, or own class containing more info. (i.e. browser info, IP adderss...)

(Quote is from this link) This should help you: http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections

EDIT

Providing a bit more information:

I believe the simplest solution for your question is to use groups. http://www.asp.net/signalr/overview/guide-to-the-api/working-with-groups

Your hub class would contain a method to join a group:

public Task JoinGroup(string groupName)
{
    return Groups.Add(Context.ConnectionId, groupName);
}

public Task LeaveGroup(string groupName)
{
    return Groups.Remove(Context.ConnectionId, groupName);
}

And let's say a PostMessage to group which sends to a given group only:

public void SendMessage(string groupName, string message, string type = "msg")
{
    var context = GlobalHost.ConnectionManager.GetHubContext<PushNotify>();
    context.Clients.Group(groupName).addNewMessageToPage(type, message);
}

When your clients join, they can connect to a group, and everything else will be handled by SignalR.

Joining the group from client and posting message:

var chat = $.connection.PushNotify;
$.connection.hub.start().done(function () {
    chat.server.joinGroup("Group1");
    chat.server.sendMessage("Group1", "Hi There");
});

Receiving messages is the same

chat.client.addNewMessageToPage = function (type, message) {
   ...
}

OTHER SOLUTION

Another solution could be using your own mapping or the SignalR Connection mapping. These solutions needs to override the OnConnected and OnDisconnected methods and map your connections. i.e.:

private readonly static ConnectionMapping<string> _connections = 
        new ConnectionMapping<string>();

public override Task OnConnected()
{
    string name = Context.User.Identity.Name;
    _connections.Add(name, Context.ConnectionId);
    return base.OnConnected();
}

public override Task OnDisconnected(bool stopCalled)
{
    string name = Context.User.Identity.Name;
    _connections.Remove(name, Context.ConnectionId);
    return base.OnDisconnected(stopCalled);
}

public void SendChatMessage(string who, string message)
{
    string name = Context.User.Identity.Name;
    foreach (var connectionId in _connections.GetConnections(who))
    {
        Clients.Client(connectionId).addChatMessage(name + ": " + message);
    }
}

Like in this example: http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections#inmemory

这篇关于SignalR推送通知与MVC4特定客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆