Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)
2016-06-26 14:53
1451 查看
简单介绍
关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现保存消息,历史消息和用户在线
由于,我这是在一个项目(【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引)的基础上做的,所以使用到的一些借口和数据表,不详细解析,只是介绍一下思路和实现方式,供大家参考
用户登录注册信息
当用户登录之后,我们注册一下用户的信息,我们在ChatHub中 新建一个方法 Register(用户帐号,用户密码)前台js调用这个方法实现用户注册
$.connection.hub.start().done(function () { chat.server.register('用户帐号', '用户密码'); });
Register方法的实现:
/// <summary> /// 用户登录注册信息 /// </summary> /// <param name="id"></param> public void Register(string account,string password) { try { //获取用户信息 var User = UserManage.Get(p => p.ACCOUNT == account); if (User != null && User.PASSWORD == password) { //更新在线状态 var UserOnline = UserOnlineManage.LoadListAll(p => p.FK_UserId == User.ID).FirstOrDefault(); UserOnline.ConnectId = Context.ConnectionId; UserOnline.OnlineDate = DateTime.Now; UserOnline.IsOnline = true; UserOnline.UserIP = Utils.GetIP(); UserOnlineManage.Update(UserOnline); //超级管理员 if (User.ID == ClsDic.DicRole["超级管理员"]) { //通知用户上线 Clients.All.UserLoginNotice("超级管理员:" + User.NAME + " 上线了!"); } else { //获取用户一级部门信息 var Depart = GetUserDepart(User.DPTID); if (Depart != null && !string.IsNullOrEmpty(Depart.ID)) { //添加用户到部门群组 Groups.Add(用户连接ID,群组) Groups.Add(Context.ConnectionId, Depart.ID); //通知用户上线 Clients.All.UserLoginNotice(Depart.NAME + " - " + CodeManage.Get(m => m.CODEVALUE == User.LEVELS && m.CODETYPE == "ZW").NAMETEXT + ":" + User.NAME + " 上线了!"); } } //刷新用户通讯录 Clients.All.ContactsNotice(JsonConverter.Serialize(UserOnline)); } } catch(Exception ex) { Clients.Client(Context.ConnectionId).UserLoginNotice("出错了:" + ex.Message); throw ex.InnerException; } }
用户上线通知,大家可以在对话框内已系统消息的方式提示,我这里是一个toastr插件的提示
//用户上线通知 chat.client.UserLoginNotice = function (message) { if ($("#LoginNotice").prop("checked")) { toasSuccess.message_t(message); } };
这里面有个判断,如果用户允许提醒,就提示,如果不允许,就不提示,就是个checkbox
当用户登录后,刷新其它用户通讯录用户的在线状态,离线用户排到底部,并且如果用户离线,点击用户的时候,提示用户离线发送邮件还是离线消息
//通讯录用户上下线 chat.client.ContactsNotice = function (message) { var data = eval("(" + message + ")"); if (!data.IsOnline) { var current = $("#charUser-" + data.FK_UserId).addClass("offline"); var parentId = current.parent().parent().prop("id"); current.remove().appendTo($("#" + parentId + " .panel-body")); }else { var current = $("#charUser-" + data.FK_UserId).removeClass("offline").attr("data-connectid", data.ConnectId); var parentId = current.parent().parent().prop("id"); current.insertBefore($("#" + parentId + " .panel-body .offline").eq(0)); } $(".panel-body .chat-user").click(function () { if ($(this).hasClass("offline")) { var MailId = $(this).attr("data-Email"); var ConnectId = $(this).attr("data-connectid"); var UserName = $(this).attr("data-username"); 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); } }); } else { ChatPerson($(this).attr("data-connectid"), $(this).attr("data-username")); } }); };
在线:
离线:
用户离线
我们重写OnDisconnected方法,当用户离线时,更新用户状态 同时刷新其它用户通讯录用户在线状态//使用者离线 public override Task OnDisconnected(bool stopCalled) { //更新在线状态 var UserOnline = UserOnlineManage.LoadListAll(p => p.ConnectId == Context.ConnectionId).FirstOrDefault(); UserOnline.ConnectId = Context.ConnectionId; UserOnline.OfflineDate = DateTime.Now; UserOnline.IsOnline = false; UserOnlineManage.Update(UserOnline); //获取用户信息 var User = UserManage.Get(p => p.ID == UserOnline.FK_UserId); Clients.All.UserLogOutNotice(User.NAME + ":离线了!"); //刷新用户通讯录 Clients.All.ContactsNotice(JsonConverter.Serialize(UserOnline)); return base.OnDisconnected(true); }
前台离线通知
//用户离线通知 chat.client.UserLogOutNotice = function (message) { if ($("#LogOutNotice").prop("checked")) { toasInfo.message_t(message); } };
获取历史消息
我是在用户登录的时候获取用户消息的,大家可以放到其它逻辑中Register方法添加用户历史消息
/// <summary> /// 用户登录注册信息 /// </summary> /// <param name="id"></param> public void Register(string account,string password) { try { //获取用户信息 var User = UserManage.Get(p => p.ACCOUNT == account); if (User != null && User.PASSWORD == password) { //更新在线状态 var UserOnline = UserOnlineManage.LoadListAll(p => p.FK_UserId == User.ID).FirstOrDefault(); UserOnline.ConnectId = Context.ConnectionId; UserOnline.OnlineDate = DateTime.Now; UserOnline.IsOnline = true; UserOnline.UserIP = Utils.GetIP(); UserOnlineManage.Update(UserOnline); //获取历史消息 int days = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["HistoryDays"]); DateTime dtHistory = DateTime.Now.AddDays(-days); var ChatMessageList = ChatMessageManage.LoadAll(p => p.MessageDate > dtHistory); //超级管理员 if (User.ID == ClsDic.DicRole["超级管理员"]) { //通知用户上线 Clients.All.UserLoginNotice("超级管理员:" + User.NAME + " 上线了!"); var HistoryMessage = ChatMessageList.OrderBy(p=>p.MessageDate).ToList().Select(p => new { UserName = UserManage.Get(m => m.ID == p.FromUser).NAME, 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, MessageType=GetMessageType(p.MessageType), p.FromUser, p.MessageContent, MessageDate = p.MessageDate.GetDateTimeFormats('D')[1].ToString() + " - " + p.MessageDate.ToString("HH:mm:ss"), ConnectId = UserOnlineManage.LoadListAll(m => m.SYS_USER.ID == p.FromUser).FirstOrDefault().ConnectId }).ToList(); //推送历史消息 Clients.Client(Context.ConnectionId).addHistoryMessageToPage(JsonConverter.Serialize(HistoryMessage)); } else { //获取用户一级部门信息 var Depart = GetUserDepart(User.DPTID); if (Depart != null && !string.IsNullOrEmpty(Depart.ID)) { //添加用户到部门群组 Groups.Add(用户连接ID,群组) Groups.Add(Context.ConnectionId, Depart.ID); //通知用户上线 Clients.All.UserLoginNotice(Depart.NAME + " - " + CodeManage.Get(m => m.CODEVALUE == User.LEVELS && m.CODETYPE == "ZW").NAMETEXT + ":" + User.NAME + " 上线了!"); //用户历史消息 int typeOfpublic = Common.Enums.ClsDic.DicMessageType["广播"]; int typeOfgroup = Common.Enums.ClsDic.DicMessageType["群组"]; int typeOfprivate = Common.Enums.ClsDic.DicMessageType["私聊"]; 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 { UserName = UserManage.Get(m => m.ID == p.FromUser).NAME, 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, MessageType = GetMessageType(p.MessageType), p.FromUser, p.MessageContent, MessageDate = p.MessageDate.GetDateTimeFormats('D')[1].ToString() + " - " + p.MessageDate.ToString("HH:mm:ss"), ConnectId = UserOnlineManage.LoadListAll(m => m.SYS_USER.ID == p.FromUser).FirstOrDefault().ConnectId }).ToList(); //推送历史消息 Clients.Client(Context.ConnectionId).addHistoryMessageToPage(JsonConverter.Serialize(HistoryMessage)); } } //刷新用户通讯录 Clients.All.ContactsNotice(JsonConverter.Serialize(UserOnline)); } } catch(Exception ex) { Clients.Client(Context.ConnectionId).UserLoginNotice("出错了:" + ex.Message); throw ex.InnerException; } }
前台:
//接收历史信息 chat.client.addHistoryMessageToPage = function (message) { var data = eval("(" + message + ")"); var html = ''; for(var i=0;i<data.length;i++) { //处理消息 } $(html).appendTo(".chat-discussion"); $('<div class=" col-xs-12 m-t-sm m-b-sm text-center sysmessage"> — 以上是历史消息 — </div>').appendTo(".chat-discussion"); };
发送广播、组播消息
/// <summary> /// 发送消息(广播、组播) /// </summary> /// <param name="message">发送的消息</param> /// <param name="message">发送的群组</param> public void Send(string message,string groupId) { try { //消息用户主体 var UserOnline = UserOnlineManage.LoadListAll(p => p.ConnectId == Context.ConnectionId).FirstOrDefault(); //广播 if(string.IsNullOrEmpty(groupId)) { //保存消息 ChatMessageManage.Save(new Domain.SYS_CHATMESSAGE() { FromUser = UserOnline.FK_UserId, MessageType = Common.Enums.ClsDic.DicMessageType["广播"], MessageContent = message, MessageDate = DateTime.Now, MessageIP = Utils.GetIP() }); //返回消息实体 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 }; //推送消息 Clients.All.addNewMessageToPage(JsonConverter.Serialize(Message)); } //组播 else { //保存消息 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 }); //返回消息实体 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 }; //推送消息 Clients.Group(groupId).addNewMessageToPage(JsonConverter.Serialize(Message)); //如果用户不在群组中则单独推送消息给用户 var Depart = GetUserDepart(UserOnline.SYS_USER.DPTID); if(Depart==null) { //推送给用户 Clients.Client(Context.ConnectionId).addNewMessageToPage(JsonConverter.Serialize(Message)); } else if(Depart.ID!=groupId) { //推送给用户 Clients.Client(Context.ConnectionId).addNewMessageToPage(JsonConverter.Serialize(Message)); } } } catch(Exception ex) { //推送系统消息 Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:消息发送失败,请稍后再试!"); throw ex.InnerException; } }
发送私聊消息
/// <summary> /// 发送给指定用户(单播) /// </summary> /// <param name="clientId">接收用户的连接ID</param> /// <param name="message">发送的消息</param> public void SendSingle(string clientId, string message) { try { //接收用户连接为空 if (string.IsNullOrEmpty(clientId)) { //推送系统消息 Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:用户不存在!"); } else { //消息用户主体 var UserOnline = UserOnlineManage.LoadListAll(p => p.ConnectId == Context.ConnectionId).FirstOrDefault(); //接收消息用户主体 var ReceiveUser = UserOnlineManage.LoadListAll(p => p.ConnectId == clientId).FirstOrDefault(); if (ReceiveUser == null) { //推送系统消息 Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:用户不存在!"); } else { //保存消息 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() }); //返回消息实体 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 }; if (ReceiveUser.IsOnline) { //推送给指定用户 Clients.Client(clientId).addNewMessageToPage(JsonConverter.Serialize(Message)); } //推送给用户 Clients.Client(Context.ConnectionId).addNewMessageToPage(JsonConverter.Serialize(Message)); } } } catch (Exception ex) { //推送系统消息 Clients.Client(Context.ConnectionId).addSysMessageToPage("系统消息:消息发送失败,请稍后再试!"); throw ex.InnerException; } }
前台发送消息:
$.connection.hub.start().done(function () { chat.server.register('用户帐号', '用户密码'); //文本框回车推送 $("#sendMessage").keyup(function (event) { if (event.keyCode == 13 || event.which == 13) { if ($.trim($(this).val()) == '' || $.trim($(this).val()).length < 1) { $(this).val($.trim($(this).val())); $(this).focus(); return false; } else { //私聊 if ($.trim($("#person").val()) != '' && $.trim($("#person").val()).length > 1) { chat.server.sendSingle($("#person").val(), $(this).val()); } else { chat.server.send($(this).val(), $("#group").val()); } $(this).val("").focus(); } } }); });
前台接收消息:
//接收服务器信息 chat.client.addNewMessageToPage = function (message) { var data = eval("(" + message + ")"); var html = ''; //处理消息 $(html).appendTo(".chat-discussion"); $('.chat-discussion').scrollTop($('.chat-discussion')[0].scrollHeight); if(!$("#small-chat-box").hasClass("active")) { messagecount = messagecount + 1; } if (messagecount > 0) { $("#small-chat .badge").html(messagecount); } }; //接收系统消息 chat.client.addSysMessageToPage = function (message) { $('<div class=" col-xs-12 m-t-sm m-b-sm text-center sysmessage">' + message + '</div>').appendTo(".chat-discussion"); $('.chat-discussion').scrollTop($('.chat-discussion')[0].scrollHeight); };
离线:
上线:
私聊:
组聊:
原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com
相关文章推荐
- 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递
- 开源新闻速递:RaspAnd 发行版可以将树莓派 3 变成一台完备的 Android 计算机
- ASP连接Access2013
- 学习记录1--Raspberry Pi 烧录系统镜像
- ASP.NET解决客户端服务器ID不一致-ClientID与ClientIDMode
- ASP.NET MVC Razor
- aspx NVelocity 模板使用
- asp.net中使用单例
- log4net在Asp.net Mvc中的应用配置与介绍
- Asp.NET的Trace追踪
- 从Microsoft.AspNet.Identity看微软推荐的一种MVC的分层架构
- 使用整体模型模板辅助器 Using Whole-Model Templated Helpers 模板辅助器方法 精通ASP.NET MVC 5
- Creating Form Elements --Using BeginForm and EndForm 使用内建的Form辅助器方法 精通ASP.NET MVC 5
- Creating Custom Helper Methods 创建自定义辅助器方法----辅助器方法 ------ 精通ASP.NET MVC 5
- ASP.NET 序列化
- asp.net WebService实现跨域js调用功能实现
- Aspose.Cells生成Excel 服务器不用安装office
- ASP.NET输入文本框自动提示功能
- asp.net获取当前页面的url地址
- asp.net Textbox获取焦点并且内容全选