简单介绍

关于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());
}
$(".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(, ) : UserManage.Get(m => m.ID == p.FromUser).FACE_IMG,
MessageType=GetMessageType(p.MessageType),
p.FromUser,
p.MessageContent,
MessageDate = p.MessageDate.GetDateTimeFormats('D')[].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(, ) : UserManage.Get(m => m.ID == p.FromUser).FACE_IMG,
MessageType = GetMessageType(p.MessageType),
p.FromUser,
p.MessageContent,
MessageDate = p.MessageDate.GetDateTimeFormats('D')[].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=;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(, ) : UserOnline.SYS_USER.FACE_IMG, MessageDate = DateTime.Now.GetDateTimeFormats('D')[].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(, ) : UserOnline.SYS_USER.FACE_IMG, MessageDate = DateTime.Now.GetDateTimeFormats('D')[].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(, ) : UserOnline.SYS_USER.FACE_IMG, MessageDate = DateTime.Now.GetDateTimeFormats('D')[].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 == || event.which == )
{
if ($.trim($(this).val()) == '' || $.trim($(this).val()).length < ) {
$(this).val($.trim($(this).val()));
$(this).focus();
return false;
}
else {
//私聊
if ($.trim($("#person").val()) != '' && $.trim($("#person").val()).length > ) {
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')[].scrollHeight);
if(!$("#small-chat-box").hasClass("active"))
{
messagecount = messagecount + ;
}
if (messagecount > )
{
$("#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')[].scrollHeight);
};

离线:

上线:

私聊:

组聊:

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

Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)的更多相关文章

  1. Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)

    简介       ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端 ...

  2. Asp.NET websocket,Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)

    ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及 ...

  3. 在 Asp.NET MVC 中使用 SignalR 实现推送功能 [转]

    在 Asp.NET MVC 中使用 SignalR 实现推送功能 罗朝辉 ( http://blog.csdn.net/kesalin ) CC许可,转载请注明出处 一,简介 Signal 是微软支持 ...

  4. MVC 中使用 SignalR 实现推送功能

    MVC 中使用 SignalR 实现推送功能 一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Pus ...

  5. 史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式

    1.概述 通过前两篇 史上最全面的SignalR系列教程-1.认识SignalR 史上最全面的SignalR系列教程-2.SignalR 实现推送功能-永久连接类实现方式 文章对SignalR的介绍, ...

  6. 使用 SignalR 实现推送功能

    百度搜索:使用 SignalR 实现推送功能

  7. Asp.NET MVC 中使用 SignalR 实现推送功能

    一,简介Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请 ...

  8. 在 Asp.NET MVC 中使用 SignalR 实现推送功能

    一,简介Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请 ...

  9. 史上最全面的SignalR系列教程-2、SignalR 实现推送功能-永久连接类实现方式

    1.概述 通过上篇史上最全面的SignalR系列教程-1.认识SignalR文章的介绍,我们对SignalR技术已经有了一个全面的了解.本篇开始就通过SignalR的典型应用的实现方式做介绍,例子虽然 ...

随机推荐

  1. Linux碎碎念

    在学习Linux过程中,有许多有用的小技巧.如果放在纸质的笔记本上,平时查阅会相当不方便.现在以一种“碎碎念”的方式,汇集整理在此,目前还不是很多,但随着学习.工作的深入,后续会陆陆续续添加更多的小技 ...

  2. javascript运动系列第一篇——匀速运动

    × 目录 [1]简单运动 [2]定时器管理 [3]分享到效果[4]移入移出[5]运动函数[6]透明度[7]多值[8]多物体[9]回调[10]函数完善[11]最终函数 前面的话 除了拖拽以外,运动也是j ...

  3. css知多少之绝对定位小记

    一.position定位常见属性 对于属性position来说,属性值有static/relative/absolute/fixed/inherit以下只对绝对定位position:absolute详 ...

  4. Function.prototype.toString 的使用技巧

    Function.prototype.toString这个原型方法可以帮助你获得函数的源代码, 比如: function hello ( msg ){ console.log("hello& ...

  5. 在禅道中实现WORD等OFFICE文档转换为PDF进行在线浏览

    条件: 安装好禅道的服务器 能直接浏览PDF的浏览器(或通过 安装插件实现 ) 文档转换服务程序(建议部署在另一台服务器上)     实现 原理: 修改禅道的文件预览功能(OFFICE文档其使用的是下 ...

  6. 如何使用dos命令打开当前用户、当前日期、当前时间以及当前用户加当前时间?

    1.dos命令安装mysqld --stall.启动net start mysql.进入MySQL数据库mysql -uroot -p后,输入select user();当前用户 select cur ...

  7. MongoDB备份(mongodump)和恢复(mongorestore)

    MongoDB提供了备份和恢复的功能,分别是MongoDB下载目录下的mongodump.exe和mongorestore.exe文件 1.备份数据使用下面的命令: >mongodump -h ...

  8. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  9. LINQ Group By操作

    在上篇文章 .NET应用程序与数据库交互的若干问题 这篇文章中,讨论了一个计算热门商圈的问题,现在在这里扩展一下,假设我们需要从两张表中统计出热门商圈,这两张表内容如下: 上表是所有政区,商圈中的餐饮 ...

  10. 是时候搁置Grunt,耍一耍gulp了

    也算是用了半年Grunt,几个月前也写过一篇它的入门文章(点此查看),不得不说它是前端项目的一个得力助手.不过技术工具跟语言一样日新月异,总会有更好用的新的东西把旧的拍死在沙滩上(当然Grunt肯定没 ...