前面讲到用Cache来实现在线用户存储,今天主要改为单列模式来实现这个列表存储。
OnlineUser.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace ClassLibrary1
{
public class OnlineUser
{
private Dictionary<string, string> dd = new Dictionary<string, string>();
private static OnlineUser s_Instance = new OnlineUser();
private object m_OnlineMembers_Locker = new object();
/// <summary>
/// 在线列表池的唯一实例
/// </summary>
public static OnlineUser Instance
{
get { return s_Instance; }
}
public void CreateOnLine()
{
lock (m_OnlineMembers_Locker)
{
if (dd.ContainsKey(HttpContext.Current.Session.SessionID))
{
dd.Remove(HttpContext.Current.Session.SessionID);
}
dd.Add(HttpContext.Current.Session.SessionID, HttpContext.Current.User.Identity.Name);
}
}
public Dictionary<string, string> GetDD()
{
return dd;
}
public void Remove(string userId)
{
dd.Remove(userId);
}
}
}
Login
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ClassLibrary1;
namespace WebApplication8
{
public partial class WebForm1 : System.Web.UI.Page
{
private static object o = new object();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Request.Cookies["Name"] != null && Request.Cookies["Password"] != null)
{
this.txtName.Text = Request.Cookies["Name"].Value;
this.txtPwd.Attributes["value"] = Request.Cookies["Password"].Value;
}
}
}
protected void btnLogin_Click(object sender, EventArgs e)
{
if (MemberInfo.GetUserList().Contains(this.txtName.Text))
{
Response.Cookies["Name"].Expires = DateTime.Now.AddDays(-1);
Response.Cookies["Password"].Expires = DateTime.Now.AddDays(-1);
if (CheckBoxRememberMe.Checked)
{
Response.Cookies["Name"].Expires = DateTime.Now.AddDays(7);
Response.Cookies["Password"].Expires = DateTime.Now.AddDays(7);
}
Response.Cookies["Name"].Value = this.txtName.Text.Trim();
Response.Cookies["Password"].Value = this.txtPwd.Text.Trim();
var ticket = new System.Web.Security.FormsAuthenticationTicket(1, this.txtName.Text, DateTime.Now, DateTime.Now.AddDays(1), false, "USER");
var encryptedTicket = System.Web.Security.FormsAuthentication.Encrypt(ticket);
if (Request.Cookies[System.Web.Security.FormsAuthentication.FormsCookieName] != null)
Request.Cookies.Remove(System.Web.Security.FormsAuthentication.FormsCookieName);
var loginIdentify = new HttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName);
loginIdentify.Expires = DateTime.Now.AddDays(1);
loginIdentify.Value = encryptedTicket;
Response.AppendCookie(loginIdentify);
Session.Abandon();
if (!String.IsNullOrEmpty(Request.QueryString["ReturnUrl"]) && !Request.QueryString["ReturnUrl"].ToLower().Contains("profile"))
Response.Redirect(Server.UrlDecode(Request.QueryString["ReturnUrl"]));
else
Response.Redirect(System.Web.Security.FormsAuthentication.DefaultUrl);
}
}
public void CreateCacheOnLine()
{
Dictionary<string, string> DD = new Dictionary<string, string>();
if (HttpContext.Current.Cache["cacheName"] != null)
{
DD = (Dictionary<string, string>)HttpContext.Current.Cache["cacheName"];
if (DD.ContainsKey(HttpContext.Current.Session.SessionID))
{
DD.Remove(HttpContext.Current.Session.SessionID);
}
}
DD.Add(HttpContext.Current.Session.SessionID,this.txtName.Text);
HttpContext.Current.Cache.Insert("cacheName", DD, null, DateTime.Now.AddMinutes(60), System.Web.Caching.Cache.NoSlidingExpiration);
}
}
}
WebForm.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="WebApplication8.WebForm2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
function OnLine() {
$.getJSON("Handler1.ashx?" + (Math.random() + new Date().getMilliseconds()) + "", null, function (data) {
$("#tbUserList").html("");
var str = "<tr><td>memberName</td><td>是否在线</td></tr>";
$.each(data.userList, function (i, item) {
if (item.onLine == "yes")
str += "<tr><td>" + item.memberName + "</td><td>在线</td></tr>";
else
str += "<tr><td>" + item.memberName + "</td><td>离线</td></tr>";
});
$("#tbUserList").append(str);
})
}
window.setInterval(OnLine, 1000);//1000*60
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<table id="tbUserList">
</table>
<asp:Button ID="Button1" runat="server" Text="退出" οnclick="Button1_Click" />
</div>
</form>
</body>
</html>
WebForm2.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ClassLibrary1;
using System.Web.Security;
namespace WebApplication8
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// ClassLibrary1.OnlineUser.Instance.CreateOnLine();
}
protected void Button1_Click(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
Session.Abandon();
Response.Redirect(Request.Url.ToString());
}
}
}
Handler1.ashx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ClassLibrary1;
namespace WebApplication8
{
/// <summary>
/// Handler1 的摘要说明
/// </summary>
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Dictionary<string, string> dd = OnlineUser.Instance.GetDD();
sb.Append("{\"userList\":[");
foreach(var userList in MemberInfo.GetUserList())
{
if (dd.ContainsValue(userList))
sb.Append("{\"memberName\":\""+userList+"\",\"onLine\":\"yes\"},");
else
sb.Append("{\"memberName\":\"" + userList + "\",\"onLine\":\"no\"},");
}
sb.Remove(sb.Length-1, 1);
sb.Append("]}");
context.Response.Write(sb.ToString());
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using ClassLibrary1;
namespace WebApplication8
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
}
protected void Session_Start(object sender, EventArgs e)
{
Application.Lock();
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
OnlineUser.Instance.CreateOnLine();
}
Application.UnLock();
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
Application.Lock();
OnlineUser.Instance.Remove(Session.SessionID);
Application.UnLock();
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}