关于系统的SignalR的即时通讯功能

来源:互联网 发布:小米网络摄像头怎么用 编辑:程序博客网 时间:2024/05/16 15:15

提供的功能如下:

1、在线聊天

2、心跳包检测机制

3、群聊

首先,巧妇难为无米之炊,这是总所周知的。这里我们需要两个东西,一个是Asp.net MVC4项目;另一个是Signalr组件。接着在项目中,新建一个文件夹名称为Hubs,在这个文件夹下面新建一个名称为ClientPushHub的类,定义如下:


public class ClientPushHub : Hub
 {
        private UsersOnLineBLL blluseronline = new UsersOnLineBLL();

        public void Connect(string userID)
        {
            UsersOnLine useronline = blluseronline.FindByID(userID);
            useronline.ConnectionIds = GetConnectionIds(this.Context.ConnectionId,useronline.ConnectionIds);
            useronline.OnlineCount = 0;
            useronline.IsOnline = true;
            useronline.OnlineTime = DateTime.Now;
            blluseronline.Update(useronline,userID);

            ChatHub chatHub = new Hubs.ChatHub();
            Clients.All.loginUser(chatHub.GetOnlineUsersOnHub());
        }

        public void TriggerHeartbeat(string userID)
        {
            UsersOnLine useronline = new UsersOnLine();
            useronline.OnlineCount = 0;
            useronline.OnlineTime = DateTime.Now;
            blluseronline.UpdateByCondition(useronline, string.Format("UserID='{0}'", userID), new string[] { "OnlineCount", "OnlineTime" });
        }

        private string GetConnectionIds(string ConnectionId,string ConnectionIds)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (!string.IsNullOrEmpty(ConnectionIds))
            {
                string[] array = ConnectionIds.Split(',');
                if (array.Length < 10)
                {
                    sb.Append(ConnectionIds);
                    sb.Append(",");
                }
            }

            sb.Append(ConnectionId);
            return sb.ToString();
        }

这个类的设计思想有如下几个部分:

首先,所有用户的登陆信息,我持久化到了数据库中,定义如下:

 [Table("KTD_UsersOnLine", "UserID")]
    public class UsersOnLine:BaseEntity
    {
        /// <summary>
        /// 用户主键
        /// <summary>
        private string userID = string.Empty;
        /// <summary>
        /// 用户主键
        /// <summary>
        [PrimaryKey(PrimaryKeyType.Assign, "UserID", DbType.String)]
        public string UserID
        {
            get { return userID; }
            set { userID = value; }
        }


        /// <summary>
        /// 
        /// <summary>
        private string description = string.Empty;
        /// <summary>
        /// 
        /// <summary>
        [Colum("Description")]
        public string Description
        {
            get { return description; }
            set { description = value; }
        }


        /// <summary>
        /// 
        /// <summary>
        private bool isOnline = false;
        /// <summary>
        /// 
        /// <summary>
        [Colum("IsOnline", DbType.Boolean)]
        public bool IsOnline
        {
            get { return isOnline; }
            set { isOnline = value; }
        }


        /// <summary>
        /// 
        /// <summary>
        private int onlineCount = 0;
        /// <summary>
        /// 
        /// <summary>
        [Colum("OnlineCount", DbType.Int32)]
        public int OnlineCount
        {
            get { return onlineCount; }
            set { onlineCount = value; }
        }


        /// <summary>
        /// 
        /// <summary>
        private DateTime? onlineTime = null;
        /// <summary>
        /// 
        /// <summary>
        [Colum("OnlineTime", DbType.DateTime)]
        public DateTime? OnlineTime
        {
            get { return onlineTime; }
            set { onlineTime = value; }
        }


        /// <summary>
        /// 
        /// <summary>
        private string onlineIP = string.Empty;
        /// <summary>
        /// 
        /// <summary>
        [Colum("OnlineIP")]
        public string OnlineIP
        {
            get { return onlineIP; }
            set { onlineIP = value; }
        }


        private string connectionIds = string.Empty;
        [Colum("ConnectionIds")]
        public string ConnectionIds
        {
            get { return connectionIds; }
            set { connectionIds = value; }
        }
    }

这样,用户登陆信息就会保存到数据库中,一旦有新用户进来或者是旧用户退出,我就可以通过更新数据库用户在线信息,维护完毕,将数据库用户在线信息推到前端。这样前台用户就能实时看到,哪些用户上线,哪些用户下线了。

其次,心跳包检测机制部分,前端用户每隔5秒钟会发送一次心跳包到处理中心,处理中心收到心跳包,会将更新数据库用户在线时间;也就是说,如果用户登陆正常,那么数据库用户在线时间每隔5秒钟自动更新;但是如果用户不按正常渠道退出(直接关闭浏览器或者在任务管理器中关闭浏览器),那么数据库用户在线时间更新会停止,通过判断用户在线时间提示当前用户已经断开连接。

 public bool CheckAlive(UsersOnLine client)
        {
            if (client != null)
            {
                return client.OnlineTime.Value.AddSeconds(10) > DateTime.Now;
            }
            return false;
        }

 if (Timer == null)
            Timer = new Timer();
            Timer.Interval = 1000; 
            Timer.Start();
            Timer.Elapsed += (sender, args) =>
            {
                List<UsersOnLine> list = blluseronline.Find(string.Format("UserID<>'{0}' AND IsOnline = 1", userID));
                foreach (UsersOnLine useronline in list)
                {
                    if (!chatHub.CheckAlive(useronline))
                    {
                        useronline.IsOnline = false;
                        useronline.ConnectionIds = string.Empty;
                        blluseronline.Update(useronline, useronline.UserID);
                        chat.Clients.All.loginUser(chatHub.GetOnlineUsersOnHub());
                    }
                }
            };

这就是处理中心的所有内容了。

打开登陆界面,首先输入用户名和密码进入系统:


在线聊天:


群组聊天:


前台部分代码:

<script type="text/javascript">
        var clientPushHub = $.connection.clientPushHub;


        clientPushHub.begin = function () {
             $.jGrowl.defaults.animateClose = { width: 'hide' };
             $.jGrowl("系统登陆成功!!", { life: 500 });
        };


        clientPushHub.client.onPushingMessage = function (message) {
            var content = "";
            if(message.sendType=="0"){
                var senderID = message.senderID;
                if (message.senderID.split("|").length > 1){
                    senderID = message.senderID.split("|")[0];
                }
                var id = "win_" + senderID;
                if($("#"+id).length==0){
                     $("#msgTip_cmd a").addClass("newTip");
                     ShowWinTipMsg(senderID);
                }else{
                     AppendChatMsg(senderID, message.nickname, message.sendTime, message.msgContent, true);
                }
                content = message.msgContent;
            }else{
                content = message.msgTitle;
            }
            var title = message.sendTypeName+"-"+message.sender;
            $.jGrowl("<span>"+content+"</span>", { header: title, sticky: true });
        }


        clientPushHub.client.loginUser = function (userlist) {
            var currentUserID = "@Model.UserItem.UserID";
            $("#onlineuserlist").empty();
            for (i = 0; i < userlist.length; i++) {
                if (userlist[i].UserID == currentUserID) {
                      $("#onlineuserlist").append("<li id='online_" + userlist[i].UserID + "'><span class='on'></span><div class='c' id='" + userlist[i].UserID + "'>" + userlist[i].Description + "</div></li>");
                }
            }
            for (i = 0; i < userlist.length; i++) {
                if (userlist[i].UserID != currentUserID) {
                    $("#onlineuserlist").append("<li onclick='AddChatWin(\"" + userlist[i].UserID + "\",\"" + userlist[i].Description + "\"," + userlist[i].IsOnline + ")' id='online_" + userlist[i].UserID + "'><span class='on'></span><div class='c' id='" + userlist[i].UserID + "'>" + userlist[i].Description + "</div></li>");
                }
            }
            $("#online_span").html(userlist.length);
        };


        $.connection.hub.start().done(function () {
            clientPushHub.begin();
            registerEvents(clientPushHub,"@Model.UserItem.UserID")
        });


        function registerEvents(clientPushHub,userid) {
            clientPushHub.server.connect(userid);

            setInterval(function () {
                clientPushHub.server.triggerHeartbeat(userid);
            }, 5000);
        }

        function CreateWebEditer(obj, fid, isGroup) {
            obj.tinymce({
                script_url: "@Url.Content("~/JavaScript/tiny_mce/tiny_mce.js")",
                language: "ch",
                theme: "advanced",
                plugins: "pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist",
                theme_advanced_buttons1: "bold,italic,underline,strikethrough,|,fontselect,fontsizeselect,|,forecolor,|,emotions,|,removeformat", //,|,image",
                theme_advanced_buttons2: "",
                theme_advanced_buttons3: "",
                theme_advanced_buttons4: "",
                theme_advanced_toolbar_location: "top",
                theme_advanced_toolbar_align: "left",
                theme_advanced_resizing: true,
                content_css: "Style/content.css",
                setup: function (ed) {
                    ed.onKeyDown.add(function (ed, e) {
                        //HotKeyPress(e, fid, isGroup);
                    });
                }
            });
        }
</script>


0 0
原创粉丝点击