我找到了一个关于在Asp.Net中统计在线用户的代码。我将它添加到我的MVC项目,但它无法正常工作。有一个自定义Httpmodule,它有一个Init()函数,并在每个请求中调用它。问题出在哪里。
init()必须在所有应用程序生命周期中运行一次,但它在每个请求上运行。 这段代码在asp.net上运行良好,但由于init()方法在每个请求中都运行,因此它无法在MVC上运行。
public class OnlineUsersModule : IHttpModule
{
private static Int32 _sessionTimeOut = 20; // Set Default to 20 Minutes
private static List<OnlineUserInfo> _onlineUsers = null;
public static List<OnlineUserInfo> OnlineUsers
{
get
{
CleanExpiredSessions();
return _onlineUsers;
}
}
private static void CleanExpiredSessions()
{
_onlineUsers.RemoveAll(delegate(OnlineUserInfo user)
{
return user.SessionStarted.AddMinutes(_sessionTimeOut) < DateTime.Now;
});
}
#region IHttpModule Members
public void Init(HttpApplication context)
{
_onlineUsers = new List<OnlineUserInfo>();
// Get the Current Session State Module
SessionStateModule module = context.Modules["Session"] as SessionStateModule;
module.Start += new EventHandler(Session_Start);
}
private void Session_Start(object sender, EventArgs e)
{
HttpRequest Request = HttpContext.Current.Request;
HttpApplicationState Application = HttpContext.Current.Application;
HttpSessionState Session = HttpContext.Current.Session;
// Get Session TimeOut
_sessionTimeOut = HttpContext.Current.Session.Timeout;
Application.Lock();
OnlineUserInfo user = new OnlineUserInfo();
user.SessionId = Session.SessionID;
user.SessionStarted = DateTime.Now;
user.UserAgent = !String.IsNullOrEmpty(Request.UserAgent)
? Request.UserAgent : String.Empty;
user.IPAddress = !String.IsNullOrEmpty(Request.UserHostAddress)
? Request.UserHostAddress : String.Empty;
if (Request.UrlReferrer != null)
{
user.UrlReferrer = !String.IsNullOrEmpty(Request.UrlReferrer.OriginalString)
? Request.UrlReferrer.OriginalString : String.Empty;
}
else
{
user.UrlReferrer = String.Empty;
}
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
user.CurrentUser = HttpContext.Current.User;
}
// Add the New User to Collection
_onlineUsers.Add(user);
Application.UnLock();
}
public void Dispose()
{
}
#endregion
}
public class OnlineUserInfo
{
public String UserAgent { get; set; }
public String SessionId { get; set; }
public String IPAddress { get; set; }
public String UrlReferrer { get; set; }
public DateTime SessionStarted { get; set; }
public IPrincipal CurrentUser { get; set; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("UserAgent = {0} | ", UserAgent);
sb.AppendFormat("SessionId = {0} | ", SessionId);
sb.AppendFormat("IPAddress = {0} | ", IPAddress);
sb.AppendFormat("UrlReferrer = {0} | ", UrlReferrer);
sb.AppendFormat("SessionStarted = {0}", SessionStarted);
return sb.ToString();
}
}
另外我认为还有一个问题。当我向init()方法添加断点时,在推送F10之后它进入init()的开始意味着有其他线程试图运行init()这是一个问题吗?
答案 0 :(得分:4)
HttpModules住在游泳池里。当您的应用程序启动并将其放入池中时,ASP.NET进程会创建并初始化它们(可配置的)数量。
然后,每次请求进入实例时,都会从池中获取并分配给请求服务。目前没有初始化。完成请求的处理后,将实例放回池中以供以后使用。
在负载很重的情况下,系统可以决定创建更多HttpModules实例
HTH
答案 1 :(得分:3)
也许您每次都使用Cassini并重新编译应用程序 F5 ,这会产生每次请求都会调用Init
方法的错觉。