zoukankan      html  css  js  c++  java
  • signalr中Group 分组群发消息的简单使用

    前一段时间写了几篇关于signalr的文章

    1.MVC中使用signalR入门教程

    2.mvc中signalr实现一对一的聊天

    3.Xamarin android中使用signalr实现即时通讯

    在平时的工作中用到了signalr进行消息的推送,所以总结了这几篇文章,今天我就来写一写这个signalr如何使用Group 分组方法群发消息。更全面地了解和学习使用signalr。

    在开始学习Signalr Group群发消息之前我们来看一下所实现的效果图:



    强大的signalr已经封装好了Group方法,已经在Hub里面集成了Groups分组管理,关键的使用方法如下:


    //加入Group组方法
    //Context.ConnectionId 连接ID,每个页面连接集线器即会产生唯一ID
    //roomName分组的名称
    Groups.Add(Context.ConnectionId, roomName);
    
    //移除Group组
    Groups.Remove(Context.ConnectionId, roomName);
    
    //作用:调用分组内连接对象,注册客户端Js方法
    //Room:分组名称
    //new string[0]:过滤(不发送)的连接ID数组
    // msg:消息内容
     Clients.Group(Room, new string[0]).sendMsg(Room,msg)
    
    
    在客户端中调用:
    
    chat.client.sendMsg=function(Room,msg){}
    
    
    
    当然在实际中如何实现,看下接下来的代码
    namespace signalrGroupDemo.Models
    {
        public class DbContext
        {
            public DbContext()
            {
                Users = new List<User>();
                Connections = new List<Connection>();
                Rooms = new List<Room>();
            }
            //用户集合
            public List<User> Users { get; set; }
    
            //连接集合
            public List<Connection> Connections { get; set; }
    
            //房间集合
            public List<Room> Rooms { get; set; }
        }
        //用户类
        public class User
        {
           [Key]
            public string UserName { get; set; }
           //用户连接
           public List<Connection> Connections { get; set; }
            //用户房间集合
            public virtual List<Room> Rooms { get; set; }
            public User()
            {
                Connections = new List<Connection>();
                Rooms = new List<Room>();
            }
        }
        public class Connection
        {
            //连接ID
            public string ConnectionID { get; set; }
            //用户代理
            public string userAgent { get; set; }
            //是否连接
            public bool Connected { get; set; }
        }
        //房间类
        public class Room
        {
            [Key]
            public string RommName { get; set; }
           //用户集合
           public virtual List<User> Users { get; set; }
            public Room() {
                Users = new List<User>();
            }
        }
    }
    
    

    第二步:引入Signalr类库,添加Hub集线器类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    using signalrGroupDemo.Models;
    using Newtonsoft.Json;
    using Microsoft.AspNet.SignalR.Hubs;
    
    namespace signalrGroupDemo
    {
        [HubName("groupHub")]
        public class GroupHUb : Hub
        {
            public void Hello()
            {
                Clients.All.hello();
            }
            public static DbContext db = new DbContext();
            /// <summary>
            /// 重写Hub连接事件
            /// </summary>
            /// <returns></returns>
            public override Task OnConnected()
            {
                //查询用户
                var user = db.Users.Where(w => w.UserName == Context.ConnectionId).FirstOrDefault();
                //判断用户是否存在
                if (user == null)
                {
                    user = new User()
                    {
                        UserName = Context.ConnectionId
                    };
                    db.Users.Add(user);
                }
                //发送房间列表
                var rooms = db.Rooms.Select(p => p.RoomName).ToList();
                //注册getRooms 获取房间的方法
                Clients.Client(Context.ConnectionId).getRoomList(JsonConvert.SerializeObject(rooms));
                return base.OnConnected();
            }
            //更新所有用户的房间列表
            private void GetRooms()
            {
                var rooms =JsonConvert.SerializeObject(db.Rooms.Select(p => p.RoomName).ToList());
                Clients.All.getRoomList(rooms);
            }
    
            //重写Hub链接断开事件
            public override Task OnDisconnected(bool s)
            {
                var user = db.Users.Where(u=>u.UserName==Context.ConnectionId).FirstOrDefault();
                //判断用户是否存在,存在则删除
                if (user != null)
                {
                    //删除用户
                    db.Users.Remove(user);
    
                }
                return base.OnDisconnected(s);
            }
            //加入聊天室
            public void AddRoom(string  roomName)
            {
                //查询聊天室
                var room = db.Rooms.Find(a=>a.RoomName==roomName);
                //存在则加入
                if (room != null)
                {
                    //查找房间中是否存在此用户
                    var isUser = room.Users.Where(w => w.UserName == Context.ConnectionId).FirstOrDefault();
                    //不存在则加入
                    if (isUser == null)
                    {
                        var user = db.Users.Find(a => a.UserName == Context.ConnectionId);
                        user.Rooms.Add(room);
                        room.Users.Add(user);
                        Groups.Add(Context.ConnectionId, roomName);
                        //注册加入聊天室的addRoom方法
                        Clients.Client(Context.ConnectionId).addRoom(roomName);
                    }
                    else
                    {
                        Clients.Client(Context.ConnectionId).showMessage("请勿重复加入房间");
                    }
                }
            }
            //创建聊天室
            public void CreateRoom(string  roomName)
            {
                var room = db.Rooms.Find(a=>a.RoomName==roomName);
                if (room == null)
                {
                    Room r = new Room() { RoomName = roomName };
                    //将房间加入列表
                    db.Rooms.Add(r);
                    AddRoom(roomName);
                    Clients.Client(Context.ConnectionId).showMessage("房间创建完成");
                    GetRooms();
                }
                else
                {
                    Clients.Client(Context.ConnectionId).showMessage("房间名重复");
                }
            }
            //退出聊天室
            public void ExitRoom(string  roomName)
            {
                //查找房间是否存在
                var room = db.Rooms.Find(a=>a.RoomName==roomName);
                //存在则删除
                if (room != null)
                {
                    //查找要删除的用户
                    var user = room.Users.Where(p => p.UserName == Context.ConnectionId).FirstOrDefault();
                    //移除此用户
                    room.Users.Remove(user);
                    //如果房间人数为0,怎删除房间
                    if (room.Users.Count == 0)
                    {
                        db.Rooms.Remove(room);
                    }
                    //Groups Remove移除分组方法
                    Groups.Remove(Context.ConnectionId,roomName);
                    //提示客户端
                    Clients.Client(Context.ConnectionId).removeRoom("退出成功");
                }
            }
            //给分组内所有用户发送消息
            public void SendMsg(string  Room,string  Message)
            {
                Clients.Group(Room, new string[0]).sendMessage(Room,Message+" "+DateTime.Now.ToString());
            }
        }
    }

    第三步:前端调用注册的Server方法和注册Client方法

    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>signalr group 分组方法的使用</title>
        <script src="~/Scripts/jquery-1.10.2.min.js"></script>
        <script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>
         @*这里是虚拟目录,也就是你再OWIN Startup中注册的地址*@
        <script src="~/signalr/hubs"></script>
    </head>
    <body>
        <div><div>名称:<p id="userName"></p></div>
            房间名:<input  type="text" value="ceshi" id="roomName"/>
            <button id="createRoom">创建聊天室</button></div>  
        <div style="float:left;border:double">
            <div>房间列表</div><ul id="roomList"></ul>
        </div>
        <div id="rooms"></div>
        <script>
        var  chat;
        var roomCount =0;
        $(function(){
            chat = $.connection.groupHub;
            //调用hub中注册的showMessage方法
            chat.client.showMessage= function (message)
            {
                alert(message);
            }
            //调用hub中注册的sendMessage 方法
            chat.client.sendMessage= function (roomname, message)
            {
                debugger
                $("#" + roomname).find("ul").each(function () {
                    $(this).append('<li>'+message+'</li>');
                })
            }
            //调用hub中removeRoom 退出房间方法
            chat.client.removeRoom = function (data)
            {
                alert(data);
            }
            //注册查询房间列表的方法
            chat.client.getRoomList = function (data) {
                
                if (data) {
                    debugger
                    var jsonData = $.parseJSON(data);
                    $("#roomList").html(" ");
                    for (var i = 0; i < jsonData.length; i++) {
                        var html = '<li>房间名:' + jsonData[i] + '<button roomName="' + jsonData[i] + '" onclick="addRoom(this)">加入</button> </li>'
                        $("#roomList").append(html);
                    }
                }
            }
            //调用hub中addRoom 加入房间的方法
            chat.client.addRoom = function (roomName)
            {
                var html = '<div style="float:left; margin-left:30px; border:double" id="' + roomName + '" roomname="' + roomName + '" ><button onclick="removeRoom(this)">退出房间</button> 
                              ' + roomName + '房间聊天记录如下:<ul></ul> <input type="text"/> <button onclick="send(this)">发送</button><div>'
                $("#rooms").append(html);
            }
    
    
            //获取用户名称
            $("#userName").html(prompt('请输入您的名称:', ''));
            $.connection.hub.start().done(function () {
                $("#createRoom").click(function ()
                {
                    if (roomCount < 2) {
                        chat.server.createRoom($("#roomName").val());
                    }
                    else
                    {
                        alert("聊天窗口只允许有2个");
                    }
                })
            })
    
        })
      
            //发送消息的方法
            function send(btn)
            {
                
                var message = $(btn).prev().val();
                var room = $(btn).parent();
                var userName = $("#userName").html();
                message = userName + ":" + message;
                var roomName = $(room).attr("roomName");
                chat.server.sendMsg(roomName,message);
            }
            //退出房间
            function removeRoom(btn)
            {
                var room = $(btn).parent();
                var roomName = $(room).attr("roomName");
                chat.server.exitRoom(roomName);
            }
            //加入房间
            function addRoom(roomName)
            {
                var data = $(roomName).attr("roomName");
                chat.server.addRoom(data);
            }
        
        </script>
    </body>
    </html>
  • 相关阅读:
    Redis为什么要自己实现一个SDS
    Redis中的数据结构
    编程题
    设计模式-代理模式
    设计模式-原型模式
    设计模式-工厂模式(简单工厂,工厂方法,抽象工厂)
    Redis基础
    Windows提高_1.4进程通信
    Windows提高_1.3文件操作
    Windows提高_1.2遍历进程、遍历模块
  • 原文地址:https://www.cnblogs.com/zhangmumu/p/7374782.html
Copyright © 2011-2022 走看看