java项目上线下线_解决 MVC 用户上线下线状态问题

以前工作项目中就有一个微博类功能,其中也出现了用户在线和离线的问题。

但是因为初入程序猿 使用的是 Session _end 上个事件。 Session _end 这个事件不需要怎么解释吧 就是在seesion过期的时候所触发的事件,但有BUG啊! 因为 iis中由于有进程回收机制,系统繁忙的话Session会丢失。 当然 微软解决又弄了个 进程外seesion 来解决了一下 。额 当时楞是没想起来为啥 ,还是经验少啊。

今天突然看了些  在线状态的问题  突发奇想   想自己不适用Seesion _end  来做一个 在线状态的实现。  百度了半天 还是没啥收获,最后决定  得  自己写吧!

首先想到就是 利用静态对象  得特性 (在程序执行前就创建好对象并且知道程序结束之前不会被释放掉。)前几天从新看了一下进程和线程   进程和线程执行是通过操作系统维护的一个进程表维护着的 调度器  调整执行的。 所以就联想到 在管道事件 Application_Start() 中来维护一个 静态集合对象 通过定时器 实现 session_end 这个事件

Globel.asax.cs 文件中添加一个事件

public classMvcApplication : System.Web.HttpApplication

{protected voidApplication_Start()

{

AreaRegistration.RegisterAllAreas();

WebApiConfig.Register(GlobalConfiguration.Configuration);

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

RouteConfig.RegisterRoutes(RouteTable.Routes);

BundleConfig.RegisterBundles(BundleTable.Bundles);//开启一个定时器 并且执行一个方法

StatusMy.GetStatusMy().TestTimer();

}

}

StatusMy 对象类 是关键的问题 代码并不多 应该很好理解

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Web;namespaceOnlineStatus.Models

{usingSystem.Data.Entity;usingSystem.Data.Entity.Infrastructure;usingSystem.Data.Entity.Validation;usingOnlineStatus.Models.Model;public classStatusMy : System.Web.HttpApplication

{#region 单例

privateStatusMy()

{

}private staticStatusMy IStatusMy;public staticStatusMy GetStatusMy()

{return IStatusMy ?? (IStatusMy = newStatusMy());

}#endregion

///

///定义定时器 如果是public 很有可能被GC掉///

privateSystem.Threading.Timer timerClose;///

///定义个静态集合///

private static ListlistMy;///

///定义一个 Lock 的时候使用的 Object 可以使用this 但是如果当前的这个this 是public 的话会有可能出现异常 保险期间还是使用MSDN 官方///

private object thisLock = new object();///

///执行定时器///

public voidTestTimer()

{

timerClose= new System.Threading.Timer(ToMyContent, null, 0, 30000);

}///

///利用Application的特性 维护一个 集合表 表中记录了最后一次网站时间 如果最后一次访问时间 小于服务器时间20分钟者在数据库中设置为 离线状态///

///

///The o.///

private void ToMyContent(objecto)

{if (listMy == null || listMy.Count <= 0)

{return;

}

DbContext db= MyDbContext.GetCurrentEFContext();//使用的是CallContxt 确保当前进程内唯一//定义一个变量用来判断 维护着的List 对象是否有值 方便最后EF统一执行SQL 语句

int i = 0;foreach (MyUser myContent inlistMy)

{

TimeSpan s= new TimeSpan(0, 0, 0, 20);//这是时间差为20分钟

System.TimeSpan ts= DateTime.Now.Subtract(myContent.UTime); //通过当前服务器时间减去用户最后一次访问服务器的时间的出来的 时间差

if (ts

{continue; //跳出这次循环 不执行 if 后续代码

}//做修改标注

User u = new User { ID = myContent.ID, Status = false, UTime = myContent.UTime, Name =myContent.Name };

DbEntityEntry entry = db.Entry(u);

entry.State=System.Data.EntityState.Modified;

entry.Property(a=> a.Status).IsModified = true;

i++;

}if (i == 0)

{return;

}try{

db.SaveChanges();

}catch(DbEntityValidationException dbEx)

{

}

}///

///用户访问的 将其添加维护到 集合中///

///

public voidAddList(User u)

{if (u == null && u.ID <= 0)return;

MyUser myU= new MyUser { ID = u.ID, Name = u.Name, UTime = DateTime.Now, Status =u.Status };if (listMy == null)

{lock(thisLock)

{

listMy= new List{ myU };

}return;

}

MyUser m= listMy.FirstOrDefault(c => c.ID ==myU.ID);if (m != null && m.ID != 0)

{lock(thisLock)

{

listMy.Remove(m);

listMy.Add(myU);

}

}else{lock(thisLock)

{

listMy.Add(myU);

}

}

}

}

}

MyDbContext类   线程唯一   EF上下文的问题 你懂的

public static classMyDbContext

{public staticDbContext GetCurrentEFContext()

{

DbContext dbContext= CallContext.GetData("EFContext") asDbContext;if (dbContext==null)

{

dbContext= newModel1Container();

dbContext.Configuration.ValidateOnSaveEnabled= true;

CallContext.SetData("EFContext", dbContext);

}returndbContext;

}

}

MVC 的全局过滤器  可以做到  不管用户访问那个服务器页面 都可以进行操作。 额  面向切面编程?

在 FilterConfig 类中添加过滤器类

public classFilterConfig

{public static voidRegisterGlobalFilters(GlobalFilterCollection filters)

{

filters.Add(newHandleErrorAttribute());

filters.Add(newOnlineStatus.Controllers.LoginValidateAttribute());

}

}

LoginValidateAttribute  自定义过滤器的实现

public classLoginValidateAttribute : System.Web.Mvc.AuthorizeAttribute

{public override voidOnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)

{//判断 请求的 控制器是不是等于指定的控制器 如果不留下一个不用验证的控制器 那么就会一直在服务器跳转

if (filterContext.RouteData.Values["controller"].ToString() != "RegisterLogin")

{#region 1.验证用户是否登陆(Session && Cookie)

//1.验证用户是否登陆(Session && Cookie)

if (!OnlineStatus.Controllers.Help.ToHelp().IsLogin())

{

filterContext.Result= filterContext.Result = new RedirectResult("/RegisterLogin/index");

}#endregion }

}

}

ToHelp 类 的实现

public classHelp

{privateHelp()

{

}private staticHelp Ihelp;public staticHelp ToHelp()

{return Ihelp ?? (Ihelp = newHelp());

}#region 0.1 Http上下文 及 相关属性

///

///Http上下文///

HttpContext ContextHttp

{get{returnHttpContext.Current;

}

}

HttpResponse Response

{get{returnContextHttp.Response;

}

}

HttpRequest Request

{get{returnContextHttp.Request;

}

}

System.Web.SessionState.HttpSessionState Session

{get{returnContextHttp.Session;

}

}#endregion

#region 2.1 当前用户对象 +MODEL.Ou_UserInfo Usr

//

///当前用户对象///

publicModels.User Usr

{get{return Session["name"] asModels.User;

}set{

Session["name"] =value;

}

}#endregion

///

///验证用户是否登录///

///

public boolIsLogin()

{if (Session["name"] == null)

{if (Request.Cookies["name"] == null)

{return false;

}string strUser = Request.Cookies["name"].Value;int userid = int.Parse(strUser);

DbContext db=MyDbContext.GetCurrentEFContext();

OnlineStatus.Models.User use= db.Set().FirstOrDefault(c => c.ID ==userid);if (use == null && use.ID <= 0)

{return false;

}

Usr=use;//将其添加到维护的 状态集合中

StatusMy.GetStatusMy().AddList(use);

}return true;

}///

///登录 这里就简单写了 名称密码都对 就true 不对 false 额 以为是想简单写一下 数据库居然没弄密码 额///

///

///

///

public bool Login(stringname)

{

DbContext db=MyDbContext.GetCurrentEFContext();

OnlineStatus.Models.User use= db.Set().FirstOrDefault(c => c.Name ==name);if (use == null && use.ID >= 0)

{return false;

}//将其添加到维护的 状态集合中

StatusMy.GetStatusMy().AddList(use);return true;

}

}

我试了试 OK

一直都是自己一个人研究来研究去的 冒泡出来 纯粹是来 希望和大神们交流一下 ,请大神们指点一下。

不喜勿喷。

看帖 求评论啊, 真的很希望能有人 指点指点啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值