关于系统的SignalR的即时通讯功能
来源:互联网 发布:小米网络摄像头怎么用 编辑:程序博客网 时间:2024/05/16 15:15
提供的功能如下:
1、在线聊天
2、心跳包检测机制
3、群聊
首先,巧妇难为无米之炊,这是总所周知的。这里我们需要两个东西,一个是Asp.net MVC4项目;另一个是Signalr组件。接着在项目中,新建一个文件夹名称为Hubs,在这个文件夹下面新建一个名称为ClientPushHub的类,定义如下:
public class ClientPushHub : Hub
{
private UsersOnLineBLL blluseronline = new UsersOnLineBLL();
public void Connect(string userID)
{
UsersOnLine useronline = blluseronline.FindByID(userID);
useronline.ConnectionIds = GetConnectionIds(this.Context.ConnectionId,useronline.ConnectionIds);
useronline.OnlineCount = 0;
useronline.IsOnline = true;
useronline.OnlineTime = DateTime.Now;
blluseronline.Update(useronline,userID);
ChatHub chatHub = new Hubs.ChatHub();
Clients.All.loginUser(chatHub.GetOnlineUsersOnHub());
}
public void TriggerHeartbeat(string userID)
{
UsersOnLine useronline = new UsersOnLine();
useronline.OnlineCount = 0;
useronline.OnlineTime = DateTime.Now;
blluseronline.UpdateByCondition(useronline, string.Format("UserID='{0}'", userID), new string[] { "OnlineCount", "OnlineTime" });
}
private string GetConnectionIds(string ConnectionId,string ConnectionIds)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
if (!string.IsNullOrEmpty(ConnectionIds))
{
string[] array = ConnectionIds.Split(',');
if (array.Length < 10)
{
sb.Append(ConnectionIds);
sb.Append(",");
}
}
sb.Append(ConnectionId);
return sb.ToString();
}
这个类的设计思想有如下几个部分:
首先,所有用户的登陆信息,我持久化到了数据库中,定义如下:
[Table("KTD_UsersOnLine", "UserID")]
public class UsersOnLine:BaseEntity
{
/// <summary>
/// 用户主键
/// <summary>
private string userID = string.Empty;
/// <summary>
/// 用户主键
/// <summary>
[PrimaryKey(PrimaryKeyType.Assign, "UserID", DbType.String)]
public string UserID
{
get { return userID; }
set { userID = value; }
}
/// <summary>
///
/// <summary>
private string description = string.Empty;
/// <summary>
///
/// <summary>
[Colum("Description")]
public string Description
{
get { return description; }
set { description = value; }
}
/// <summary>
///
/// <summary>
private bool isOnline = false;
/// <summary>
///
/// <summary>
[Colum("IsOnline", DbType.Boolean)]
public bool IsOnline
{
get { return isOnline; }
set { isOnline = value; }
}
/// <summary>
///
/// <summary>
private int onlineCount = 0;
/// <summary>
///
/// <summary>
[Colum("OnlineCount", DbType.Int32)]
public int OnlineCount
{
get { return onlineCount; }
set { onlineCount = value; }
}
/// <summary>
///
/// <summary>
private DateTime? onlineTime = null;
/// <summary>
///
/// <summary>
[Colum("OnlineTime", DbType.DateTime)]
public DateTime? OnlineTime
{
get { return onlineTime; }
set { onlineTime = value; }
}
/// <summary>
///
/// <summary>
private string onlineIP = string.Empty;
/// <summary>
///
/// <summary>
[Colum("OnlineIP")]
public string OnlineIP
{
get { return onlineIP; }
set { onlineIP = value; }
}
private string connectionIds = string.Empty;
[Colum("ConnectionIds")]
public string ConnectionIds
{
get { return connectionIds; }
set { connectionIds = value; }
}
}
这样,用户登陆信息就会保存到数据库中,一旦有新用户进来或者是旧用户退出,我就可以通过更新数据库用户在线信息,维护完毕,将数据库用户在线信息推到前端。这样前台用户就能实时看到,哪些用户上线,哪些用户下线了。
其次,心跳包检测机制部分,前端用户每隔5秒钟会发送一次心跳包到处理中心,处理中心收到心跳包,会将更新数据库用户在线时间;也就是说,如果用户登陆正常,那么数据库用户在线时间每隔5秒钟自动更新;但是如果用户不按正常渠道退出(直接关闭浏览器或者在任务管理器中关闭浏览器),那么数据库用户在线时间更新会停止,通过判断用户在线时间提示当前用户已经断开连接。
public bool CheckAlive(UsersOnLine client)
{
if (client != null)
{
return client.OnlineTime.Value.AddSeconds(10) > DateTime.Now;
}
return false;
}
if (Timer == null)
Timer = new Timer();
Timer.Interval = 1000;
Timer.Start();
Timer.Elapsed += (sender, args) =>
{
List<UsersOnLine> list = blluseronline.Find(string.Format("UserID<>'{0}' AND IsOnline = 1", userID));
foreach (UsersOnLine useronline in list)
{
if (!chatHub.CheckAlive(useronline))
{
useronline.IsOnline = false;
useronline.ConnectionIds = string.Empty;
blluseronline.Update(useronline, useronline.UserID);
chat.Clients.All.loginUser(chatHub.GetOnlineUsersOnHub());
}
}
};
打开登陆界面,首先输入用户名和密码进入系统:
在线聊天:
群组聊天:
前台部分代码:
<script type="text/javascript">
var clientPushHub = $.connection.clientPushHub;
clientPushHub.begin = function () {
$.jGrowl.defaults.animateClose = { width: 'hide' };
$.jGrowl("系统登陆成功!!", { life: 500 });
};
clientPushHub.client.onPushingMessage = function (message) {
var content = "";
if(message.sendType=="0"){
var senderID = message.senderID;
if (message.senderID.split("|").length > 1){
senderID = message.senderID.split("|")[0];
}
var id = "win_" + senderID;
if($("#"+id).length==0){
$("#msgTip_cmd a").addClass("newTip");
ShowWinTipMsg(senderID);
}else{
AppendChatMsg(senderID, message.nickname, message.sendTime, message.msgContent, true);
}
content = message.msgContent;
}else{
content = message.msgTitle;
}
var title = message.sendTypeName+"-"+message.sender;
$.jGrowl("<span>"+content+"</span>", { header: title, sticky: true });
}
clientPushHub.client.loginUser = function (userlist) {
var currentUserID = "@Model.UserItem.UserID";
$("#onlineuserlist").empty();
for (i = 0; i < userlist.length; i++) {
if (userlist[i].UserID == currentUserID) {
$("#onlineuserlist").append("<li id='online_" + userlist[i].UserID + "'><span class='on'></span><div class='c' id='" + userlist[i].UserID + "'>" + userlist[i].Description + "</div></li>");
}
}
for (i = 0; i < userlist.length; i++) {
if (userlist[i].UserID != currentUserID) {
$("#onlineuserlist").append("<li onclick='AddChatWin(\"" + userlist[i].UserID + "\",\"" + userlist[i].Description + "\"," + userlist[i].IsOnline + ")' id='online_" + userlist[i].UserID + "'><span class='on'></span><div class='c' id='" + userlist[i].UserID + "'>" + userlist[i].Description + "</div></li>");
}
}
$("#online_span").html(userlist.length);
};
$.connection.hub.start().done(function () {
clientPushHub.begin();
registerEvents(clientPushHub,"@Model.UserItem.UserID")
});
function registerEvents(clientPushHub,userid) {
clientPushHub.server.connect(userid);
setInterval(function () {
clientPushHub.server.triggerHeartbeat(userid);
}, 5000);
}
function CreateWebEditer(obj, fid, isGroup) {
obj.tinymce({
script_url: "@Url.Content("~/JavaScript/tiny_mce/tiny_mce.js")",
language: "ch",
theme: "advanced",
plugins: "pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist",
theme_advanced_buttons1: "bold,italic,underline,strikethrough,|,fontselect,fontsizeselect,|,forecolor,|,emotions,|,removeformat", //,|,image",
theme_advanced_buttons2: "",
theme_advanced_buttons3: "",
theme_advanced_buttons4: "",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_resizing: true,
content_css: "Style/content.css",
setup: function (ed) {
ed.onKeyDown.add(function (ed, e) {
//HotKeyPress(e, fid, isGroup);
});
}
});
}
</script>
- 关于系统的SignalR的即时通讯功能
- 关于即时通讯系统开发的问题
- 即时通讯系统的想法
- 即时通讯系统的应用
- 即时通讯系统的应用
- 基于SignalR的小型IM系统
- 基于SignalR的小型IM系统
- 关于全球即时通讯系统架构的点滴思考
- 关于即时通讯的一点记录
- 关于即时通讯的一点记录
- 用SignalR 2.0开发客服系统[系列4:负载均衡的情况下使用SignalR]
- SignalR 2.0 系列:SignalR的服务器广播
- 屏蔽微软的SignalR
- 关于用微软实时推送SignalR的相关bug
- 功能完善的即时通讯+视频会议源码
- Linux即时通讯应用系统的音视频功能实现 音视频SDK
- 用SignalR 2.0开发客服系统[系列5:使用SignalR的中文简体语言包和其他技术点]
- 搭建基于Openfire的即时通讯系统
- [Linux起步]配置Java和Eclipse环境
- 马尔科夫链
- Unity3D—transform和Input
- 网络编程之WCF编程:WCF服务和客户端的建立,回调
- Unity之Transform和Input
- 关于系统的SignalR的即时通讯功能
- zjut_1178 最小公倍数
- C----------------LessonPointerHigher
- python里面的一些小知识点
- 2015 4399校园招聘游戏开发笔试题
- C---------------LessonDynamicMemory
- C++ vector 的resize和reverve
- Linux core 文件
- HDU--1029--Ignatius and the Princess IV