上次的探討沒有任何結果,我瀏覽了大量的文章和個別系統的參考!決定用Cache來做,這可能有點難以接受但是配合mvc過濾器來做效果非常好!
由於之前的過濾器我們用過了OnActionExecuting這個方法來判斷權限
現在在方法被執行后我們用OnActionExecuted來監聽用戶的操作和刷新用戶在線列表
首先下載http://files.cnblogs.com/ymnets/OnlineUser.7z這個類庫,代碼清晰,並加注釋
這個類庫包括了操作在線用戶列表的增刪方法,大家可以下載下來看並放到
可以打開研究其代碼!
在App.Admin新建類OnlineHttpModule
using App.Core.OnlineStat; using App.Models.Sys; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Web.Routing; namespace App.Admin { public class OnlineHttpModule { // 緩存鍵 public static readonly string g_onlineUserRecorderCacheKey = "__OnlineUserRecorder"; #region IHttpHandler 成員 public static void ProcessRequest() { // 獲取在線用戶記錄器 OnlineUserRecorder recorder = HttpContext.Current.Cache[g_onlineUserRecorderCacheKey] as OnlineUserRecorder; if (recorder == null) { // 創建記錄器工廠 OnlineUserRecorderFactory factory = new OnlineUserRecorderFactory(); // 設置用戶超時時間 factory.UserTimeOutMinute = 2; // 統計時間間隔 factory.StatisticEventInterval = 20; // 創建記錄器 recorder = factory.Create(); // 緩存記錄器 HttpContext.Current.Cache.Insert(g_onlineUserRecorderCacheKey, recorder); } OnlineUser user = new OnlineUser(); AccountModel model = (AccountModel)HttpContext.Current.Session["Account"];//注意session的名稱是和登錄保存的名稱一致 // 用戶名稱 user.UserName = Convert.ToString(model.Id); // SessionID user.SessionID = HttpContext.Current.Session.SessionID; // IP 地址 user.ClientIP = HttpContext.Current.Request.UserHostAddress; // 最后活動時間 user.ActiveTime = DateTime.Now; // 最后請求地址 user.RequestURL = HttpContext.Current.Request.RawUrl; // 保存用戶信息 recorder.Persist(user); } #endregion } }
這個類在用戶登錄時被調用和在過濾器被調用,調用代碼
過濾器:
public class SupportFilterAttribute : ActionFilterAttribute { public string ActionName { get; set; } private string Area; // 方法被執行后的更新在線用戶列表 public override void OnActionExecuted(ActionExecutedContext filterContext) { OnlineHttpModule.ProcessRequest(); } ......................................
登錄時候的設置:
AccountModel account = new AccountModel(); account.Id = user.Id; account.TrueName = user.TrueName; account.Photo = string.IsNullOrEmpty(user.Photo)?"/Images/Photo.jpg":user.Photo; Session["Account"] = account; //在線用戶統計 OnlineHttpModule.ProcessRequest();
調用非常簡單,實現非常簡單!
現在看看如果獲取在線列表:
// 綁定在線用戶列表 IList<OnlineUser> userList = recorder.GetUserList(); foreach (var OnlineUser in userList) { sb.AppendFormat(OnlineUser.UserName+"<br>"); }
OnlineHttpModule可以自由設置統計的間隔(秒),和用戶超時的時間,這很精准的統計了用戶2分鍾無操作被視為離線!
我分別用IE和chome測試了2個用戶,同時也關閉瀏覽器測試用戶,准確性也不錯!拋棄了不准確的原始老方法