zoukankan      html  css  js  c++  java
  • Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)

    简单介绍

    关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)

    在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现保存消息,历史消息和用户在线

    由于,我这是在一个项目(【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引)的基础上做的,所以使用到的一些借口和数据表,不详细解析,只是介绍一下思路和实现方式,供大家参考

    用户登录注册信息

    当用户登录之后,我们注册一下用户的信息,我们在ChatHub中 新建一个方法 Register(用户帐号,用户密码)

    前台js调用这个方法实现用户注册 

    1 $.connection.hub.start().done(function () {            
    2             chat.server.register('用户帐号', '用户密码');           
    3         });

     Register方法的实现:

    复制代码
     1 /// <summary>
     2         /// 用户登录注册信息
     3         /// </summary>
     4         /// <param name="id"></param>
     5         public void Register(string account,string password)
     6         {
     7             try
     8             {
     9                 //获取用户信息
    10                 var User = UserManage.Get(p => p.ACCOUNT == account);
    11                 if (User != null && User.PASSWORD == password)
    12                 {
    13                     //更新在线状态
    14                     var UserOnline = UserOnlineManage.LoadListAll(p => p.FK_UserId == User.ID).FirstOrDefault();
    15                     UserOnline.ConnectId = Context.ConnectionId;
    16                     UserOnline.OnlineDate = DateTime.Now;
    17                     UserOnline.IsOnline = true;
    18                     UserOnline.UserIP = Utils.GetIP();
    19                     UserOnlineManage.Update(UserOnline);
    20                     
    21 
    22                     //超级管理员
    23                     if (User.ID == ClsDic.DicRole["超级管理员"])
    24                     {
    25                         //通知用户上线
    26                         Clients.All.UserLoginNotice("超级管理员:" + User.NAME + " 上线了!");
    27 
    28                     }
    29                     else
    30                     {
    31                         //获取用户一级部门信息
    32                         var Depart = GetUserDepart(User.DPTID);
    33                         if (Depart != null && !string.IsNullOrEmpty(Depart.ID))
    34                         {
    35                             //添加用户到部门群组 Groups.Add(用户连接ID,群组)
    36                             Groups.Add(Context.ConnectionId, Depart.ID);
    37                             //通知用户上线
    38                             Clients.All.UserLoginNotice(Depart.NAME + " - " + CodeManage.Get(m => m.CODEVALUE == User.LEVELS && m.CODETYPE == "ZW").NAMETEXT + ":" + User.NAME + " 上线了!");
    39                             
    40 
    41                         }
    42                     }
    43                     //刷新用户通讯录
    44                     Clients.All.ContactsNotice(JsonConverter.Serialize(UserOnline));                    
    45                 }
    46             }
    47             catch(Exception ex)
    48             {
    49                 Clients.Client(Context.ConnectionId).UserLoginNotice("出错了:" + ex.Message);
    50                 throw ex.InnerException;
    51             }
    52             
    53         }
    复制代码

     用户上线通知,大家可以在对话框内已系统消息的方式提示,我这里是一个toastr插件的提示

    1 //用户上线通知
    2         chat.client.UserLoginNotice = function (message) {
    3             if ($("#LoginNotice").prop("checked")) { toasSuccess.message_t(message); }
    4         };

    这里面有个判断,如果用户允许提醒,就提示,如果不允许,就不提示,就是个checkbox

    当用户登录后,刷新其它用户通讯录用户的在线状态,离线用户排到底部,并且如果用户离线,点击用户的时候,提示用户离线发送邮件还是离线消息

    复制代码
     1 //通讯录用户上下线
     2         chat.client.ContactsNotice = function (message) {
     3             var data = eval("(" + message + ")");
     4             if (!data.IsOnline) {
     5                 var current = $("#charUser-" + data.FK_UserId).addClass("offline");
     6                 var parentId = current.parent().parent().prop("id");
     7                 current.remove().appendTo($("#" + parentId + " .panel-body"));
     8             }else
     9             {
    10                 var current = $("#charUser-" + data.FK_UserId).removeClass("offline").attr("data-connectid", data.ConnectId);
    11                 var parentId = current.parent().parent().prop("id");
    12                 current.insertBefore($("#" + parentId + " .panel-body .offline").eq(0));
    13             }
    14             $(".panel-body .chat-user").click(function () {
    15                 if ($(this).hasClass("offline")) {
    16                     var MailId = $(this).attr("data-Email");
    17                     var ConnectId = $(this).attr("data-connectid");
    18                     var UserName = $(this).attr("data-username");
    19                     swal({ title: "用户离线", text: "当前用户不在线,是否发送邮件?", type: "warning", showCancelButton: true, confirmButtonColor: "#DD6B55", confirmButtonText: "发送邮件", cancelButtonText: "发送离线消息", closeOnConfirm: false, closeOnCancel: false }, function (isConfirm) { if (isConfirm) { sweetAlert.close(); document.getElementById(MailId).click(); } else { sweetAlert.close(); ChatPerson(ConnectId, UserName); } });
    20                 }
    21                 else {
    22                     ChatPerson($(this).attr("data-connectid"), $(this).attr("data-username"));
    23                 }
    24             });
    25 
    26         };
    复制代码

    在线:

    离线:

    用户离线

    我们重写OnDisconnected方法,当用户离线时,更新用户状态 同时刷新其它用户通讯录用户在线状态

    复制代码
     1  //使用者离线
     2         public override Task OnDisconnected(bool stopCalled)
     3         {
     4             //更新在线状态
     5             var UserOnline = UserOnlineManage.LoadListAll(p => p.ConnectId == Context.ConnectionId).FirstOrDefault();
     6             UserOnline.ConnectId = Context.ConnectionId;
     7             UserOnline.OfflineDate = DateTime.Now;
     8             UserOnline.IsOnline = false;
     9             UserOnlineManage.Update(UserOnline);
    10 
    11             //获取用户信息
    12             var User = UserManage.Get(p => p.ID == UserOnline.FK_UserId);
    13 
    14             Clients.All.UserLogOutNotice(User.NAME + ":离线了!");
    15             //刷新用户通讯录
    16             Clients.All.ContactsNotice(JsonConverter.Serialize(UserOnline));
    17 
    18             return base.OnDisconnected(true);
    19         }
    复制代码

    前台离线通知

    1  //用户离线通知
    2         chat.client.UserLogOutNotice = function (message) {
    3             if ($("#LogOutNotice").prop("checked")) { toasInfo.message_t(message); }
    4         };

    获取历史消息

    我是在用户登录的时候获取用户消息的,大家可以放到其它逻辑中

    Register方法添加用户历史消息

    复制代码
     1 /// <summary>
     2         /// 用户登录注册信息
     3         /// </summary>
     4         /// <param name="id"></param>
     5         public void Register(string account,string password)
     6         {
     7             try
     8             {
     9                 //获取用户信息
    10                 var User = UserManage.Get(p => p.ACCOUNT == account);
    11                 if (User != null && User.PASSWORD == password)
    12                 {
    13                     //更新在线状态
    14                     var UserOnline = UserOnlineManage.LoadListAll(p => p.FK_UserId == User.ID).FirstOrDefault();
    15                     UserOnline.ConnectId = Context.ConnectionId;
    16                     UserOnline.OnlineDate = DateTime.Now;
    17                     UserOnline.IsOnline = true;
    18                     UserOnline.UserIP = Utils.GetIP();
    19                     UserOnlineManage.Update(UserOnline);
    20 
    21                     //获取历史消息
    22                     int days = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["HistoryDays"]);
    23                     DateTime dtHistory = DateTime.Now.AddDays(-days);
    24                     var ChatMessageList = ChatMessageManage.LoadAll(p => p.MessageDate > dtHistory);                    
    25 
    26                     //超级管理员
    27                     if (User.ID == ClsDic.DicRole["超级管理员"])
    28                     {
    29                         //通知用户上线
    30                         Clients.All.UserLoginNotice("超级管理员:" + User.NAME + " 上线了!");
    31 
    32                         var HistoryMessage = ChatMessageList.OrderBy(p=>p.MessageDate).ToList().Select(p => new
    33                         {
    34                             UserName = UserManage.Get(m => m.ID == p.FromUser).NAME,
    35                             UserFace = string.IsNullOrEmpty(UserManage.Get(m => m.ID == p.FromUser).FACE_IMG) ? "/Pro/Project/User_Default_Avatat?name=" + UserManage.Get(m => m.ID == p.FromUser).NAME.Substring(0, 1) : UserManage.Get(m => m.ID == p.FromUser).FACE_IMG,
    36                             MessageType=GetMessageType(p.MessageType),
    37                             p.FromUser,
    38                             p.MessageContent,
    39                             MessageDate = p.MessageDate.GetDateTimeFormats('D')[1].ToString() + " - " + p.MessageDate.ToString("HH:mm:ss"),
    40                             ConnectId = UserOnlineManage.LoadListAll(m => m.SYS_USER.ID == p.FromUser).FirstOrDefault().ConnectId
    41                         }).ToList();
    42 
    43                         //推送历史消息
    44                         Clients.Client(Context.ConnectionId).addHistoryMessageToPage(JsonConverter.Serialize(HistoryMessage));
    45                     }
    46                     else
    47                     {
    48                         //获取用户一级部门信息
    49                         var Depart = GetUserDepart(User.DPTID);
    50                         if (Depart != null && !string.IsNullOrEmpty(Depart.ID))
    51                         {
    52                             //添加用户到部门群组 Groups.Add(用户连接ID,群组)
    53                             Groups.Add(Context.ConnectionId, Depart.ID);
    54                             //通知用户上线
    55                             Clients.All.UserLoginNotice(Depart.NAME + " - " + CodeManage.Get(m => m.CODEVALUE == User.LEVELS && m.CODETYPE == "ZW").NAMETEXT + ":" + User.NAME + " 上线了!");
    56                             //用户历史消息
    57                             int typeOfpublic = Common.Enums.ClsDic.DicMessageType["广播"];
    58                             int typeOfgroup = Common.Enums.ClsDic.DicMessageType["群组"];
    59                             int typeOfprivate = Common.Enums.ClsDic.DicMessageType["私聊"];
    60                             var HistoryMessage = ChatMessageList.Where(p => p.MessageType == typeOfpublic || (p.MessageType == typeOfgroup && p.ToGroup == Depart.ID) || (p.MessageType == typeOfprivate && p.ToGroup == User.ID.ToString())).OrderBy(p => p.MessageDate).ToList().Select(p => new
    61                             {
    62                                 UserName = UserManage.Get(m => m.ID == p.FromUser).NAME,
    63                                 UserFace = string.IsNullOrEmpty(UserManage.Get(m => m.ID == p.FromUser).FACE_IMG) ? "/Pro/Project/User_Default_Avatat?name=" + UserManage.Get(m => m.ID == p.FromUser).NAME.Substring(0, 1) : UserManage.Get(m => m.ID == p.FromUser).FACE_IMG,
    64                                 MessageType = GetMessageType(p.MessageType),
    65                                 p.FromUser,
    66                                 p.MessageContent,
    67                                 MessageDate = p.MessageDate.GetDateTimeFormats('D')[1].ToString() + " - " + p.MessageDate.ToString("HH:mm:ss"),
    68                                 ConnectId = UserOnlineManage.LoadListAll(m => m.SYS_USER.ID == p.FromUser).FirstOrDefault().ConnectId
    69                             }).ToList();
    70                            
    71                             //推送历史消息
    72                             Clients.Client(Context.ConnectionId).addHistoryMessageToPage(JsonConverter.Serialize(HistoryMessage));
    73 
    74                         }
    75                     }
    76                     //刷新用户通讯录
    77                     Clients.All.ContactsNotice(JsonConverter.Serialize(UserOnline));                    
    78                 }
    79             }
    80             catch(Exception ex)
    81             {
    82                 Clients.Client(Context.ConnectionId).UserLoginNotice("出错了:" + ex.Message);
    83                 throw ex.InnerException;
    84             }
    85             
    86         }
    复制代码

    前台:

    复制代码
     1 //接收历史信息
     2         chat.client.addHistoryMessageToPage = function (message) {
     3             var data = eval("(" + message + ")");
     4             var html = '';
     5             for(var i=0;i<data.length;i++)
     6             {
     7                //处理消息
     8             }                        
     9             $(html).appendTo(".chat-discussion");
    10             $('<div class=" col-xs-12 m-t-sm m-b-sm text-center sysmessage"> — 以上是历史消息 — </div>').appendTo(".chat-discussion");                        
    11         };
    复制代码

    发送广播、组播消息

    复制代码
     1 /// <summary>
     2         /// 发送消息(广播、组播)
     3         /// </summary>
     4         /// <param name="message">发送的消息</param>
     5         /// <param name="message">发送的群组</param>
     6         public void Send(string message,string groupId)
     7         {
     8             try 
     9             {
    10                 //消息用户主体
    11                 var UserOnline = UserOnlineManage.LoadListAll(p => p.ConnectId == Context.ConnectionId).FirstOrDefault();
    12                 
    13                 //广播
    14                 if(string.IsNullOrEmpty(groupId))
    15                 {
    16                     //保存消息
    17                     ChatMessageManage.Save(new Domain.SYS_CHATMESSAGE() { FromUser = UserOnline.FK_UserId, MessageType = Common.Enums.ClsDic.DicMessageType["广播"], MessageContent = message, MessageDate = DateTime.Now, MessageIP = Utils.GetIP() });
    18                     //返回消息实体
    19                     var Message = new Message() { ConnectId = UserOnline.ConnectId, UserName = UserOnline.SYS_USER.NAME, UserFace = string.IsNullOrEmpty(UserOnline.SYS_USER.FACE_IMG) ? "/Pro/Project/User_Default_Avatat?name=" + UserOnline.SYS_USER.NAME.Substring(0, 1) : UserOnline.SYS_USER.FACE_IMG, MessageDate = DateTime.Now.GetDateTimeFormats('D')[1].ToString() + " - " + DateTime.Now.ToString("HH:mm:ss"), MessageContent = message, MessageType = "public", UserId = UserOnline.SYS_USER.ID };
    20 
    21                     //推送消息
    22                     Clients.All.addNewMessageToPage(JsonConverter.Serialize(Message));
    23                 }
    24                 //组播
    25                 else
    26                 {
    27                     //保存消息
    28                     ChatMessageManage.Save(new Domain.SYS_CHATMESSAGE() { FromUser = UserOnline.FK_UserId, MessageType = Common.Enums.ClsDic.DicMessageType["群组"], MessageContent = message, MessageDate = DateTime.Now, MessageIP = Utils.GetIP(), ToGroup = groupId });
    29                     //返回消息实体
    30                     var Message = new Message() { ConnectId = UserOnline.ConnectId, UserName = UserOnline.SYS_USER.NAME, UserFace = string.IsNullOrEmpty(UserOnline.SYS_USER.FACE_IMG) ? "/Pro/Project/User_Default_Avatat?name=" + UserOnline.SYS_USER.NAME.Substring(0, 1) : UserOnline.SYS_USER.FACE_IMG, MessageDate = DateTime.Now.GetDateTimeFormats('D')[1].ToString() + " - " + DateTime.Now.ToString("HH:mm:ss"), MessageContent = message, MessageType = "group", UserId = UserOnline.SYS_USER.ID };
    31 
    32                     //推送消息
    33                     Clients.Group(groupId).addNewMessageToPage(JsonConverter.Serialize(Message));
    34                     //如果用户不在群组中则单独推送消息给用户
    35                     var Depart = GetUserDepart(UserOnline.SYS_USER.DPTID);
    36                     if(Depart==null)
    37                     {
    38                         //推送给用户
    39                         Clients.Client(Context.ConnectionId).addNewMessageToPage(JsonConverter.Serialize(Message));
    40                     }
    41                     else if(Depart.ID!=groupId)
    42                     {
    43                         //推送给用户
    44                         Clients.Client(Context.ConnectionId).addNewMessageToPage(JsonConverter.Serialize(Message));
    45                     }
    46                 }                               
    47             }
    48             catch(Exception ex)
    49             {
    50                 //推送系统消息
    51                 Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:消息发送失败,请稍后再试!");
    52                 throw ex.InnerException;
    53             }            
    54         }
    复制代码

    发送私聊消息

    复制代码
     1 /// <summary>
     2         /// 发送给指定用户(单播)
     3         /// </summary>
     4         /// <param name="clientId">接收用户的连接ID</param>
     5         /// <param name="message">发送的消息</param>
     6         public void SendSingle(string clientId, string message)
     7         {
     8             try
     9             {
    10                 //接收用户连接为空
    11                 if (string.IsNullOrEmpty(clientId))
    12                 {
    13                     //推送系统消息
    14                     Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:用户不存在!");
    15                 }
    16                 else
    17                 {
    18                     //消息用户主体
    19                     var UserOnline = UserOnlineManage.LoadListAll(p => p.ConnectId == Context.ConnectionId).FirstOrDefault();
    20                     //接收消息用户主体
    21                     var ReceiveUser = UserOnlineManage.LoadListAll(p => p.ConnectId == clientId).FirstOrDefault();
    22                     if (ReceiveUser == null)
    23                     {
    24                         //推送系统消息
    25                         Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:用户不存在!");
    26                     }
    27                     else
    28                     {
    29                         //保存消息
    30                         ChatMessageManage.Save(new Domain.SYS_CHATMESSAGE() { FromUser = UserOnline.FK_UserId, MessageType = Common.Enums.ClsDic.DicMessageType["私聊"], MessageContent = message, MessageDate = DateTime.Now, MessageIP = Utils.GetIP(), ToGroup = UserOnline.SYS_USER.ID.ToString() });
    31                         //返回消息实体
    32                         var Message = new Message() { ConnectId = UserOnline.ConnectId, UserName = UserOnline.SYS_USER.NAME, UserFace = string.IsNullOrEmpty(UserOnline.SYS_USER.FACE_IMG) ? "/Pro/Project/User_Default_Avatat?name=" + UserOnline.SYS_USER.NAME.Substring(0, 1) : UserOnline.SYS_USER.FACE_IMG, MessageDate = DateTime.Now.GetDateTimeFormats('D')[1].ToString() + " - " + DateTime.Now.ToString("HH:mm:ss"), MessageContent = message, MessageType = "private", UserId = UserOnline.SYS_USER.ID };                                        
    33                         if (ReceiveUser.IsOnline)
    34                         {
    35                             //推送给指定用户
    36                             Clients.Client(clientId).addNewMessageToPage(JsonConverter.Serialize(Message));
    37                         }
    38                         //推送给用户
    39                         Clients.Client(Context.ConnectionId).addNewMessageToPage(JsonConverter.Serialize(Message));
    40                         
    41                     }
    42                 }
    43             }
    44             catch (Exception ex)
    45             {
    46                 //推送系统消息
    47                 Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:消息发送失败,请稍后再试!");
    48                 throw ex.InnerException;
    49             }            
    50         }
    复制代码

    前台发送消息:

    复制代码
     1 $.connection.hub.start().done(function () {            
     2             chat.server.register('用户帐号', '用户密码');
     3             //文本框回车推送
     4             $("#sendMessage").keyup(function (event) {
     5                 if (event.keyCode == 13 || event.which == 13)
     6                 {
     7                     if ($.trim($(this).val()) == '' || $.trim($(this).val()).length < 1) {
     8                         $(this).val($.trim($(this).val()));
     9                         $(this).focus();
    10                         return false;
    11                     }
    12                     else {
    13                         //私聊
    14                         if ($.trim($("#person").val()) != '' && $.trim($("#person").val()).length > 1) {
    15                             chat.server.sendSingle($("#person").val(), $(this).val());
    16                         }
    17                         else {
    18                             chat.server.send($(this).val(), $("#group").val());
    19                         }
    20                         $(this).val("").focus();                       
    21                     }
    22                     
    23                 }
    24             });
    25             
    26         });
    复制代码

    前台接收消息:

    复制代码
     1 //接收服务器信息
     2         chat.client.addNewMessageToPage = function (message) {            
     3             var data = eval("(" + message + ")");
     4             var html = '';
    5 //处理消息

    19 $(html).appendTo(".chat-discussion"); 20 $('.chat-discussion').scrollTop($('.chat-discussion')[0].scrollHeight); 21 if(!$("#small-chat-box").hasClass("active")) 22 { 23 messagecount = messagecount + 1; 24 } 25 if (messagecount > 0) 26 { 27 $("#small-chat .badge").html(messagecount); 28 } 29 }; 30 //接收系统消息 31 chat.client.addSysMessageToPage = function (message) { 32 $('<div class=" col-xs-12 m-t-sm m-b-sm text-center sysmessage">' + message + '</div>').appendTo(".chat-discussion"); 33 $('.chat-discussion').scrollTop($('.chat-discussion')[0].scrollHeight); 34 };
    复制代码

    离线:

    上线:

    私聊:

    组聊:

    原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com

  • 相关阅读:
    sublime开启vim模式
    git命令行界面
    搬进Github
    【POJ 2886】Who Gets the Most Candies?
    【UVA 1451】Average
    【CodeForces 625A】Guest From the Past
    【ZOJ 3480】Duck Typing
    【POJ 3320】Jessica's Reading Problemc(尺取法)
    【HDU 1445】Ride to School
    【HDU 5578】Friendship of Frog
  • 原文地址:https://www.cnblogs.com/zhangxiaolei521/p/5808440.html
Copyright © 2011-2022 走看看