标签:
关于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
Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)
标签:
原文地址:http://www.cnblogs.com/zhangxiaolei521/p/5808440.html