SignalR框架 群组管理

  • Post author:
  • Post category:其他


SignalR 的Hub 提供了群组机制,可以把用户放到某一个或者多个组中,然后针对组进行消息推送。客户端和组之间是多对多的关系

Hub 的Groups 属性是IGroupManager 类型的,它有两个方法:


Add(string connectionId, string groupName)、

Remove(string connectionId, string groupName)

以上两个方法分别是根据connectionId 把连接加入或者从某个组移除。组的名字自定义,如果之前不存在这个组,会自动创建一个组,因此不需要单独创建组,相同groupName 为一组的。建议在OnDisconnected()中调用Remove 来移除组。

Hub 的Clients 属性是IHubCallerConnectionContext<dynamic> 类型的、

IHubCallerConnectionContext 又继承了IHubConnectionContext。所有的成员几乎都是dynamic 类

型的,所以怎么操作都可以。主要成员有:

1>



Caller



当前连接的客户端,可以通过Caller.aaa();直接调用浏览器端的function

2>



Others

,除了当前连接外的其他客户端

3>

OthersInGroup(string groupName)

名字为groupName 的组的所有成员。

4>

OthersInGroups(IList<string> groupNames)

在groupNames 这些组中的所有成员

5>

All

:所有连接的客户端

6>

AllExcept(params string[] excludeConnectionIds)

除了指定的多个ConnectionId 之外的其他

客户端

7>

Client(string connectionId)

指定的ConnectionId 对应的客户端

8>

Clients(IList<string> connectionIds)

指定的多个ConnectionId 对应的客户端

9>

Group(string groupName, params string[] excludeConnectionIds)

组groupName 中除了excludeConnectionIds 之外的客户端

10>

Groups(IList<string> groupNames, params string[] excludeConnectionIds)

组groupNames中除了excludeConnectionIds 之外的客户端

这些成员的返回值都是dynamic 类型的,有的对应一个客户端,有的对应多个客户端,无论对应几个,直接通过dynamic 调用通过Clients.All.onMessage(“hello”)这样方式通知到所有相关的客户端的js function 中。

Hub端

using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;

namespace SignalRApp
{
    public class MyHub : Hub
    {
        这个方法名字是自定义的。参数也是自定义的
        //public void SendMessage(string name, string msg)
        //{
        //    //All表示监听所有连接上来的客户端。
        //    //onMessage是一个动态的方法,名字我们可以随意定的。这里我仅仅是给他取名叫onMessage而已,我们也可以叫Clients.All.ABC();
        //    Clients.All.onMessage(name + "和大家说:" + msg);//调用所有连接上来的客户端(包括自己)监听的onMessage事件。All是一个dynamic属性,所以可以随意的监听


        //    var clientConnectionId = Context.ConnectionId; //这是与我连接的客户端的连接ID(浏览器端)

        //    //我们还可以利用QueryString类接收数据
        //    string userName = Context.QueryString["userName"];
        //    string password = Context.QueryString["password"];
        //}

        //加入组
        public void AddGroup(string groupName)
        {
            Groups.Add(this.Context.ConnectionId, groupName);//将此次连接的客户端(浏览器端)加入指定的组中
        }

        //向指定的组发送消息
        public void SendGroupMsg(string groupName,string msg)
        {
            //向指定组中(除了我之外的成员)发送消息(这个我是指此次连接上hub的客户端)
            Clients.OthersInGroup(groupName).onMessage(msg);
        }

        //重写父类OnConnected方法  :客户端连接上的时候会调用此方法
        public override Task OnConnected()
        {
            return base.OnConnected();
        }

        //重写父类OnDisconnected方法 :OnConnected方法客户端断开连接的时候会调用此方法
        public override Task OnDisconnected(bool stopCalled)
        {
            return base.OnDisconnected(stopCalled);
        }

        //重写父类OnReconnected方法  : 客户端可能网络不稳定,造成重新连接,就会调用此方法
        //注意:客户端(浏览器页面)在刷新的时候不属于重连接,刷新是属于先断开连接,然后再连接
        public override Task OnReconnected()
        {
            return base.OnReconnected();
        }
    }
}

客户端


@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/jquery.signalR-2.1.2.js"></script>
    <script src="/signalr/hubs" type="text/javascript"></script> <!--这是一个由 SignalR 处理的路径-->
</head>
<body>
    <div>
        <span>请选择要加入的组名:</span>
        <select id="AddCityGroup">
            <option>北京</option>
            <option>上海</option>
            <option>深圳</option>
            <option>广州</option>
        </select>
        <input type="button" value="加入组" id="addgroup"/><div style="padding-bottom:50px"></div>
       
        <div>以下是向选定的组发送消息内容:</div>
        <span>请选择要发送消息的组名:</span>
        <select id="CityGroup">
            <option>北京</option>
            <option>上海</option>
            <option>深圳</option>
            <option>广州</option>
        </select>
        <input type="text" id="msg" />
        <input type="button" id="btn1" value="发送消息" />
    </div>
    <script type="text/javascript">
        $(function () {
            $.connection.myHub.client.onMessage = function (msg) { //注意,这一步一定要在 $.connection.hub.start()之前执行
                alert("收到服务端发来的消息:" + msg)
            }
            //$.connection.hub.qs = { userName: "张三", password: "123456" };
            $.connection.hub.start().done(function () {
                alert("连接MyHub成功");
            }).fail(function () { alert("连接MyHub失败") });


            //加入组
            $("#addgroup").click(function () {
                var groupName = $('#AddCityGroup option:selected').text();
                $.connection.myHub.server.addGroup(groupName);//这个页面是客户端,运行Index.cshtml页面的时候,会执行这个script代码块,它会向外面指定的MyHub服务发起连接,每个连接都有一个单独的连接id,然后它会请求Myhub类中的AddGroup方法。(注意方法名的第一个字母必须小写,即便服务中的方法名是大写的)
            })

            //向指定组发送消息
            $("#btn1").click(function () {
                //注意:不管项目中声明的SignalR集线器类的中的方法名字的首字母是大写还是小写,这的名字都必须是小写开头
                //例如:我的SignalR集线器类的名字叫MyHub.cs 它里面声明了一个SendMessage方法,这里必须写成sendMessage
                //$.connection.myHub.server.sendMessage("小米", "我上市啦"); //向服务端发送消息
                var groupName = $('#CityGroup option:selected').text();
                var msg = $("#msg").val();
             
                $.connection.myHub.server.sendGroupMsg(groupName, msg);//向指定的组中发送消息
            })
        })
    </script>
</body>

</html>

测试:开几个浏览器窗口



版权声明:本文为Fanbin168原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。