简单介绍

关于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. c#语言规范

    0x00 分类 C#语言规范主要有两个来源,即我们熟知的ECMA规范和微软的规范.尽管C#的ECMA规范已经前后修订4次,但其内容仅仅到C# 2.0为止.所以慕容为了方便自己和各位方便查询,在此将常见 ...

  2. autocomplete的使用

    autocomplete使用分为本地调用方法和读取远程读取数据源的方法 (1)本地调用方法 <script src="Scripts/jquery-1.4.1.min.js" ...

  3. es6小白学习笔记(一)

    1.let和const命令 1.es6新增了let和const命令,与var用法类似,但它声明的变量只在let所在的代码块内有效(块级作用域,es5只有全局和函数作用域) { let a = 1; v ...

  4. ionic第二坑——ionic 上拉菜单(ActionSheet)安卓样式坑

    闲话不说,先上图: 这是IOS上的显示效果,代码如下: HTML部分: <body ng-app="starter" ng-controller="actionsh ...

  5. 让你从零开始学会写爬虫的5个教程(Python)

    写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个爬虫脚本是很简单的,但是对于新手来说却并不是那么容易. ...

  6. JAVA 设计模式之策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过 ...

  7. SQL-日期函数

    GETDATE() :取得当前日期时间 DATEADD (datepart , number, date ),计算增加以后的日期.参数date为待计算的日期:参数number为增量:参数datepar ...

  8. MSSQL 事务,视图,索引,存储过程,触发器

    事务 事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行. 在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的.这特别适用于多用户同时操作的数据 ...

  9. 基于select的python聊天室程序

    python网络编程具体参考<python select网络编程详细介绍>. 在python中,select函数是一个对底层操作系统的直接访问的接口.它用来监控sockets.files和 ...

  10. vim+vundle配置

    Linux环境下写代码虽然没有IDE,但通过给vim配置几个插件也足够好用.一般常用的插件主要包括几类,查找文件,查找符号的定义或者声明(函数,变量等)以及自动补全功能.一般流程都是下载需要的工具,然 ...