简单介绍

关于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. 【NLP】前戏:一起走进条件随机场(一)

    前戏:一起走进条件随机场 作者:白宁超 2016年8月2日13:59:46 [摘要]:条件随机场用于序列标注,数据分割等自然语言处理中,表现出很好的效果.在中文分词.中文人名识别和歧义消解等任务中都有 ...

  2. javascript设计模式:策略模式

    前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...

  3. [原]Redis主从复制各种环境下测试

    Redis 主从复制各种环境下测试 测试环境: Linux ubuntu 3.11.0-12-generic 2GB Mem 1 core of Intel(R) Core(TM) i5-3470 C ...

  4. WebApi返回Json格式字符串

    WebApi返回json格式字符串, 在网上能找到好几种方法, 其中有三种普遍的方法, 但是感觉都不怎么好. 先贴一下, 网上给的常用方法吧. 方法一:(改配置法) 找到Global.asax文件,在 ...

  5. WinForm设置控件焦点focus

    winform窗口打开后文本框的默认焦点设置,进入窗口后默认聚焦到某个文本框,两种方法: ①设置tabindex 把该文本框属性里的tabIndex设为0,焦点就默认在这个文本框里了. ②Winfor ...

  6. javaScript之BOM操作1

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. BPM配置故事之案例12-触发另外流程

    还记得阿海么,对就是之前的那个采购员,他又有了些意见. 阿海:小明,你看现在的流程让大家都这么方便,能不能帮个忙让我也轻松点啊-- 小明:--你有什么麻烦,现在不是已经各个部门自己提交申请了嘛? 阿海 ...

  8. Android中使用ViewFlipper实现屏幕页面切换(关于坐标轴的问题已补充更改)

    屏幕切换指的是在同一个Activity内屏幕间的切换,ViewFlipper继承了Framelayout类,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果.如 ...

  9. C++ std::array

    std::array template < class T, size_t N > class array; Code Example #include <iostream> ...

  10. Android开发学习之路-自定义控件(天气趋势折线图)

    之前写了个天气APP,带4天预报和5天历史信息.所以想着要不要加一个折线图来显示一下天气变化趋势,难得有空,就写了一下,这里做些记录,脑袋不好使容易忘事. 先放一下效果: 控件内容比较简单,就是一个普 ...