• 用SignalR 2.0开发客服系统[系列2:实现聊天室]


    前言

    交流群:195866844

    上周发表了

    用SignalR 2.0开发客服系统[系列1:实现群发通讯]

    这篇文章,得到了很多帮助和鼓励,小弟在此真心的感谢大家的支持..

    这周继续系列2,实现聊天室的功能.

    开发环境

     开发工具:VS2013 旗舰版

     数据库:未用

     操作系统:WIN7旗舰版

    正文开始

    首先我们来看看最终效果:

    正式开始:

    SignalR作为一个强大的集线器,已经在hub里面集成了Gorups,也就是分组管理,使用方法如下:

    //作用:将连接ID加入某个组
    //Context.ConnectionId 连接ID,每个页面连接集线器即会产生唯一ID
    //roomName分组的名称
    Groups.Add(Context.ConnectionId, roomName);
    
    //作用:将连接ID从某个分组移除
    Groups.Remove(Context.ConnectionId, roomName);
    
    //作用:调用分组内连接对象注册的本地JS
    //XXX:本地JS名称
    //Room:分组名称
    // new string[0]:过滤(不发送)的连接ID数组
     Clients.Group(Room, new string[0]).XXXX

    其实SignalR已经帮我们封装的很好了,关键代码其实就这三句..

    废话不多说,下面开始讲我的实现.

    首先实体类(参考微软Demo):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;
    using System.ComponentModel.DataAnnotations;
    using Microsoft.AspNet.SignalR;
    
    namespace SignalRTest
    {
        public class UserContext 
        {
            public UserContext()
            {
                Users = new List<User>();
                Connections = new List<Connection>();
                Rooms = new List<ConversationRoom>();
            }
            //用户集合
            public List<User> Users { get; set; }
            //连接集合
            public List<Connection> Connections { get; set; }
            //房间集合
            public List<ConversationRoom> Rooms { get; set; }
        }
    
        public class User
        {
            [Key]
            //用户名
            public string UserName { get; set; }
            //用户的连接
            public List<Connection> Connections { get; set; }
            //用户房间集合
            public virtual List<ConversationRoom> Rooms { get; set; }
    
            public User()
            {
                Connections = new List<Connection>();
                Rooms = new List<ConversationRoom>();
            }
        }
    
        public class Connection
        {
            //连接ID
            public string ConnectionID { get; set; }
    
            //用户代理
            public string UserAgent { get; set; }
            //是否连接
            public bool Connected { get; set; }
        }
    
        /// <summary>
        /// 房间类
        /// </summary>
        public class ConversationRoom
        {
            //房间名称
            [Key]
            public string RoomName { get; set; }
            //用户集合
            public virtual List<User> Users { get; set; }
    
    
            public ConversationRoom()
            {
                Users = new List<User>();
            }
        }
    
    }

    然后聊天室的Hub(这里我就不解释了,每句话我都加了注释,注释+代码方便大家理解..):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    using System.Threading.Tasks;
    using Microsoft.AspNet.SignalR.Hubs;
    using Newtonsoft.Json;
    
    namespace SignalRTest
    {
        [HubName("groupsHub")]
        public class GroupsHub : Hub
        {
            public static UserContext db = new UserContext();
            public void Hello()
            {
                Clients.All.hello();
            }
            /// <summary>
            /// 重写Hub连接事件
            /// </summary>
            /// <returns></returns>
            public override Task OnConnected()
            {
    
                    // 查询用户。
                    var user = db.Users.SingleOrDefault(u => u.UserName == Context.ConnectionId);
    
                    //判断用户是否存在,否则添加
                    if (user == null)
                    {
                        user = new User()
                        {
                            UserName = Context.ConnectionId
                        };
                        db.Users.Add(user);
                       
                    }
                   //发送房间列表
                    var itme = from a in db.Rooms
                               select new { a.RoomName };
                    Clients.Client(this.Context.ConnectionId).getRoomlist(JsonConvert.SerializeObject(itme.ToList()));
                return base.OnConnected();
            }
    
            /// <summary>
            /// 更新所有用户的房间列表
            /// </summary>
            private void GetRoomList()
            {
               
    
                var itme = from a in db.Rooms
                           select new { a.RoomName };
                string jsondata = JsonConvert.SerializeObject(itme.ToList());
                Clients.All.getRoomlist(jsondata);
                
            }
            /// <summary>
            /// 重写Hub连接断开的事件
            /// </summary>
            /// <returns></returns>
            public override Task OnDisconnected()
            {
                 var user = db.Users.Where(u => u.UserName == Context.ConnectionId).FirstOrDefault();
                
                    //判断用户是否存在,存在则删除
                    if (user != null)
                    {
                        //删除用户
                        db.Users.Remove(user);
                        // 循环用户的房间,删除用户
                        foreach (var item in user.Rooms)
                        {
                            RemoveFromRoom(item.RoomName);
                            
                        }
                    }
    
    
                return base.OnDisconnected();
            }
    
            /// <summary>
            /// 加入聊天室
            /// </summary>
            /// <param name="roomName"></param>
            public void AddToRoom(string roomName)
            {
                    //查询聊天室
                    var room = db.Rooms.Find(a=>a.RoomName==roomName);
                   //存在则加入
                    if (room != null)
                    {
                        //查找房间中是否存在此用户
                        var isuser = room.Users.Where(a => a.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);
                            //调用此连接用户的本地JS(显示房间)
                            Clients.Client(Context.ConnectionId).addRoom(roomName);
                        }
                        else
                        {
                            Clients.Client(Context.ConnectionId).showMessage("请勿重复加入房间!");
                        }
                    }
                   
                
            }
    
            /// <summary>
            /// 创建聊天室
            /// </summary>
            /// <param name="roomName"></param>
            public void CreatRoom(string roomName)
            {
                var room = db.Rooms.Find(a => a.RoomName == roomName);
                if (room == null)
                {
                    ConversationRoom cr = new ConversationRoom()
                    {
                        RoomName = roomName
                    };
                    //将房间加入列表
                    db.Rooms.Add(cr);
                    AddToRoom(roomName);
                    Clients.Client(Context.ConnectionId).showMessage("房间创建完成!");
                    GetRoomList();
                }
                else
                {
                    Clients.Client(Context.ConnectionId).showMessage("房间名重复!");
                }
    
            }
    
            /// <summary>
            /// 退出聊天室
            /// </summary>
            /// <param name="roomName"></param>
            public void RemoveFromRoom(string roomName)
            {
    
                    //查找房间是否存在
                var room = db.Rooms.Find(a => a.RoomName == roomName);
                  //存在则进入删除
                    if (room != null)
                    {
                        //查找要删除的用户
                        var user = room.Users.Where(a => a.UserName == Context.ConnectionId).FirstOrDefault();
                        //移除此用户
                        room.Users.Remove(user);
                        //如果房间人数为0,则删除房间
                        if (room.Users.Count <= 0)
                        {
                            db.Rooms.Remove(room);
    
                        }
                        Groups.Remove(Context.ConnectionId, roomName);
                        //提示客户端
                        Clients.Client(Context.ConnectionId).removeRoom("退出成功!");
                    }
             
                
            }
            /// <summary>
            /// 给分组内所有的用户发送消息
            /// </summary>
            /// <param name="Room">分组名</param>
            /// <param name="Message">信息</param>
            public void SendMessage(string Room, string Message)
            {
                Clients.Group(Room, new string[0]).sendMessage(Room,Message+" "+DateTime.Now.ToString());
            }
           
    
    
        }
    }

    前端HTML+JS:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title></title>
        <script src="Scripts/jquery-1.10.2.min.js"></script>
        <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
        <!--这里要注意,这是虚拟目录,也就是你在OWIN Startup中注册的地址-->
        <script src="signalr/hubs"></script>
    
        <script>
            var chat
            var roomcount = 0;
            $(function () {
                    chat = $.connection.groupsHub;
                    chat.client.showMessage = function (Message) {
    
                        alert(Message);
                    }
                    chat.client.sendMessage = function (roomname, message) {
                        $("#" + roomname).find("ul").each(function () {
                            $(this).append('<li>'+message+'</li>')
                        })
                    }
                    chat.client.removeRoom = function (data) {
                        alert(data);
                    }
                    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="SendMessage(this)">发送</button>
                                        </div>'
                        $("#RoomList").append(html);
                    }
                    //注册查询房间列表的方法
                    chat.client.getRoomlist = function (data) {
                        if (data) {
                            var jsondata = $.parseJSON(data);
                            $("#roomlist").html(" ");
                            for (var i = 0; i < jsondata.length; i++) {
                                var html = ' <li>房间名:' + jsondata[i].RoomName + '<button roomname="'+jsondata[i].RoomName+'" onclick="AddRoom(this)">加入</button></li>';
                                $("#roomlist").append(html);
                            }
                        }
                    }
                    // 获取用户名称。
                    $('#username').html(prompt('请输入您的名称:', ''));
    
                    $.connection.hub.start().done(function () {
                        $('#CreatRoom').click(function () {
                            if (roomcount < 2) {
                                chat.server.creatRoom($("#Roomname").val());
                                roomcount++;
                            } else {
                                alert("聊天窗口只允许有2个")
                            }
                        })
                    });
    
            });
            function SendMessage(btn) {
                var message = $(btn).prev().val();
                var room = $(btn).parent();
                var username = $("#username").html();
                message = username + ":" + message;
                var roomname = $(room).attr("roomname");
                chat.server.sendMessage(roomname,message);
    
            }
            function RemoveRoom(btn) {
                var room = $(btn).parent();
                var roomname = $(room).attr("roomname");
                chat.server.removeFromRoom(roomname);
            }
            function AddRoom(roomname) {
                 var data =$(roomname).attr("roomname");
                 chat.server.addToRoom(data);
            }
    
        </script>
    
    </head>
    <body>
        <div>
            <div>名称:<p id="username"></p></div>
            输入房间名:
            <input type="text" value="asdasd" id="Roomname" />
            <button id="CreatRoom">创建聊天室</button>
        </div>
        <div style="float:left;border:double">
            <div>房间列表</div>
            <ul id="roomlist">
            </ul>
        </div>
        <div id="RoomList">
        </div>
    </body>
    </html>

    至此就完成了基本的聊天室功能,有许多逻辑写的不到位的情况,请大家海涵.

    我会坚持写完本系列..

    源码下载地址:

    http://pan.baidu.com/s/1pJLxwF5

  • 相关阅读:
    解决浏览器兼容改内容的函数
    iPhone 和Android应用,特殊的链接:打电话,短信,email
    ArrayList和LinkedList的区别
    关于HashTable,HashMap和TreeMap的几点心得
    Android开发--List与ArrayList区别
    Android 版本升级涉及到的数据库数据迁移问题
    深入理解Android的startservice和bindservice
    Android之Activity的四种启动模式
    控制反转与依赖注入
    vi/vim基本使用方法
  • 原文地址:https://www.cnblogs.com/GuZhenYin/p/4626379.html
Copyright © 2020-2023  润新知