Asp.NET MVC 之心跳/长连接
0x01 在线用户类,我的用户唯一性由ID和类型识别(因为在不同的表里)
public class UserIdentity : IEqualityComparer<UserIdentity>
{
internal UserIdentity() { }
public UserIdentity(int userId, int userType)
{
this.UserID = userId;
this.UserType = userType;
}
public int UserID { get; private set; }
public int UserType { get; private set; } public bool Equals(UserIdentity x, UserIdentity y)
{
return x.UserID == y.UserID && x.UserType == y.UserType;
} public int GetHashCode(UserIdentity obj)
{
return obj.UserID * (obj.UserType + );
}
}
public class AliveUser
{
private AliveUser() { }
public AliveUser(string sessionID, int userID, int userType)
{
this.SessionID = sessionID;
this.StartAt = DateTime.Now;
this.User = new UserIdentity(userID, userType);
} public void SetExpires(DateTime expires)
{
this.Expires = expires;
}
public string SessionID { get; private set; }
public DateTime StartAt { get; private set; }
public DateTime Expires { get; private set; }
public UserIdentity User { get; private set; }
}
0x02 会话管理,线程+字典
public class AliveSessionHelper
{
static AliveSessionHelper()
{
thread.IsBackground = true;
thread.Start();
}
public static int TimeoutInMinutes = ;
private static object syncObject = new object();
public static Dictionary<string, AliveUser> OnlineUsers = new Dictionary<string, AliveUser>();
public static Dictionary<UserIdentity, List<AliveUser>> GetOnlineUsers()
{
lock (syncObject)
{
var list = OnlineUsers.Values.ToList();
var grouping = list.GroupBy(x => x.User,new UserIdentity());
var dict = new Dictionary<UserIdentity, List<AliveUser>>(grouping.Count());
foreach (var item in grouping)
{
dict.Add(item.Key, item.ToList());
}
return dict;
}
} public static void AddAliveUser(string sessionID, int userID, int userType)
{
AddAliveUser(new AliveUser(sessionID, userID, userType));
} public static void AddAliveUser(AliveUser user)
{ lock (syncObject)
{
var aliveUser = OnlineUsers.ContainsKey(user.SessionID) ? OnlineUsers[user.SessionID] : null;
if (aliveUser == null)
{
OnlineUsers.Add(user.SessionID, user);
} var expires = DateTime.Now.AddMinutes(TimeoutInMinutes);
OnlineUsers[user.SessionID].SetExpires(expires);
}
} private static Thread thread = new Thread(ThreadStartBody);
private static void ThreadStartBody()
{
while (true)
{
lock (syncObject)
{
var delList = new List<Guid>();
var list = OnlineUsers.Values.ToList();
foreach (var item in list)
{
if (item.Expires.Subtract(DateTime.Now).TotalSeconds < )
{
OnlineUsers.Remove(item.SessionID);
}
}
}
Thread.Sleep();
}
}
}
0x03 控制器实现
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
[Authorize]
public class ApiController : AsyncController
{
public async Task<ActionResult> KeepAlive()
{
if (!User.Identity.IsAuthenticated) {
return null;
}
AliveSessionHelper.AddAliveUser(Session.SessionID, AdminUserService.Instance.CurrentUserID, );
return await Task.Delay(TimeSpan.FromSeconds()).ContinueWith(task =>
{
return JavaScript("$.getScript('/admin/api/keepalive');");
});
}
}
注意
1、[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]是必须的,否则刷新(重复调用)会锁死,原理熟手自己领会,新手照做即可。
2、/admin/api/keepalive 调用的Action是自身。
3、服务端控制请求的释放间隔。这里设置的30s。如果要更长时间,如超过1分钟可能导致Action超时异常,需要加AsyncTimeoutAttribute特性设置Action超时时间大于释放间隔。
0x04 前端代码,需要jQuery。就是触发首次调用,然后就靠服务端返回js自动执行。
$(function () {
//KeepAlive
$.getScript('/admin/api/keepalive');
}
是不是感觉代码很简单?注重简单实用好用是博主一贯的追求。
拷贝请注明来源博客园,道木先生。.Net软件交流群283590657
Asp.NET MVC 之心跳/长连接的更多相关文章
- asp.net服务器推送长连接
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx. ...
- 连接弹性和命令拦截的 ASP.NET MVC 应用程序中的实体框架
最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精 上篇博客我们学习了EF 之 MVC 排序,查询,分 ...
- ASP.NET MVC 长连接(服务器推)完整实现
1.什么是"服务器推"(百科来一波)? 传统模式的 Web 系统以客户端发出请求.服务器端响应的方式工作.这种方式并不能满足很多现实应用的需求,譬如: 监控系统:后台硬件热插拔.L ...
- ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库
前段时间在园子里看到了小蝶惊鸿 发布的有关绿色版的Linux.NET——“Jws.Mono”.由于我对.Net程序跑在Linux上非常感兴趣,自己也看了一些有关mono的资料,但是一直没有时间抽出时间 ...
- Asp.Net实现Http长连接推送
话说最新帮一个朋友搞智能家居方面的东西,做一个云平台.主要作用手机在局域网外环境时对手机客户端和智能网关中命令的互相转发. 目前已经有了一个稳定的Socket版本,但是考虑到以后的扩展和性能指标要改成 ...
- 用 ASP.NET MVC 实现基于 XMLHttpRequest long polling(长轮询) 的 Comet(转)
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源. 实例:适于小型应用. 长轮询:客 ...
- 用 ASP.NET MVC 实现基于 XMLHttpRequest long polling(长轮询) 的 Comet
ASP.NET 计时器 http://www.cnblogs.com/dudu/archive/2011/10/17/2215321.html http://www.cnblogs.com/w ...
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB
您创建的MovieDBContext类负责处理连接到数据库,并将Movie对象映射到数据库记录的任务中.你可能会问一个问题,如何指定它将连接到数据库? 实际上,确实没有指定要使用的数据库,Entity ...
随机推荐
- H5 视频
HTML 5 视频 HTML5 简介 HTML5 视频/DOM 许多时髦的网站都提供视频.HTML5 提供了展示视频的标准. 检测您的浏览器是否支持 HTML5 视频: Yes! Full suppo ...
- burpsuite+sqlmap跨登录验证SQL注入
(我操作的系统是kali linux) 1.利用burpsuite代理设置拦截浏览器请求(具体操作步骤可参考:http://www.cnblogs.com/hito/p/4495432.html) 2 ...
- 在WPF应用程序中使用Font Awesome图标
Font Awesome 在网站开发中,经常用到.今天介绍如何在WPF应用程序中使用Font Awesome . 如果是自定义的图标字体,使用方法相同. 下载图标字体 在官方网站或github上下载资 ...
- 【树莓派】h2数据库操作相关
之前在树莓派上面操作时候,遇到一些业务方面的bug,和团队中的同事经过多次尝试,但就是难以重现用户现场的问题. 但是问题却实实在在地发生,虽然并不是必然可重现的bug,但是也比较闹心: 发生了问题,也 ...
- Python 爬取qqmusic音乐url并批量下载
qqmusic上的音乐还是不少的,有些时候想要下载好听的音乐,但有每次在网页下载都是烦人的登录什么的.于是,来了个qqmusic的爬虫. 至少我觉得for循环爬虫,最核心的应该就是找到待爬元素所在ur ...
- TCP协议之三次握手与四次挥手
TCP协议是TCP/IP体系中核心一个协议,该协议比起IP协议,ICMP协议,UDP协议都更复杂,因此这篇文章主要分析TCP协议在建立连接和断开连接的时候,状态转移以及报文段的内容. 下面,先放一张T ...
- Javascript动态创建 style 节点
有很多提供动态创建 style 节点的方法,但是大多数都仅限于外部的 css 文件.如何能使用程序生成的字符串动态创建 style 节点,我搞了2个小时. 静态外部 css 文件语法: @import ...
- 疑问:Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后,自动注入发生时间
问题:今天想写一个通用点的方法,根据传入的参数的类型(clazz对象),判断使用哪个mapper来插入mysql数据库. 下面是我的写法: public interface BizNeeqCommon ...
- Linux系统date命令的参数及获取时间戳的方法
date指令相关用法示例 date 用法: date [OPTION]... [+FORMAT]date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] ...
- iOS 内存泄漏
我一直以为现在都是自动内存管理了,还哪有什么内存泄漏啊.一检测才知道,不是我太相信Xcode了,就是我太单纯了.iOS开发中遇到的内存泄漏主要有几下几种: (1)对象不能释放.使用Core Fou ...