C#一个存储用户信息的类,支持单点登录
来源:互联网 发布:网络信息安全宣传周 编辑:程序博客网 时间:2024/05/21 20:21
看到这里很多问如何实现单点登录,本人根据自己的经验,提供一个实现单点登录的类。支持web和winfrom,测试成功。
利用哈希表,作为保存登录用户的队列
private static Hashtable m_userList;
设置用户在线超时的时限(我设置的是30分钟,可以根据自己的需求自行修改)
private static TimeSpan m_tsSub = new TimeSpan(0, 30, 0);
设置哈希表初始化为同步封装(为了线程安全)
m_userList = Hashtable.Synchronized(new Hashtable());
设置了几种方式
1、登录信息在数据库中验证成功后调用AddUserToList(string userName, long sessionID)
2、除登录外其他所有功能调用之前首先调用该方法 CheckUserLogin(string userName, long sessionID)
在第一种方式中,需要处理“如果用户已经登录过,则只更新登录流水号及操作时间,否则新加入队列"
该类还有个最重要的步骤就是检查保存在队列中的用户在线是否超过时限,该方法供线程调用,以便检查用户是否在线,需要保存待清理的超时在线用户的临时队列,线程每隔1分钟执行检查清理操作,遍历保存在线用户的哈希表,如果有超时的在线用户,将超时用户时放入临时的队列中,
检查完哈希表之后再进行清理操作,
不能在检查过程中执行哈希表的删除键值操作,否则会出现异常。
特别注意的是如果有超时的在线用户则进行清理操作
具体代码如下
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Threading;
namespace DllServiceLibrary
{
class HashElement
{
long m_SessionID;
DateTime m_Time;
public long SessionID
{
get { return m_SessionID; }
set { m_SessionID = value; }
}
public DateTime Time
{
get { return m_Time; }
set { m_Time = value; }
}
public HashElement()
{
m_SessionID = -1;
m_Time = DateTime.Now;
}
}
public static class UserLogin
{
//哈希表,作为保存登录用户的队列
private static Hashtable m_userList;
//检查用户在线是否超时的线程
//private static Thread m_threadQueue;
//用户在线超时的时限(30分钟)
private static TimeSpan m_tsSub = new TimeSpan(0, 30, 0);
//public static UserLogin()
public static void Init()
{
//哈希表初始化为同步封装(线程安全)
m_userList = Hashtable.Synchronized(new Hashtable());
//初始化线程
//m_threadQueue = new Thread(CheckListTO);
//m_threadQueue.IsBackground = true; //设置为后台线程
//m_threadQueue.Start();
}
public static void Empty()
{
//if (m_threadQueue.IsAlive)
//{
// m_threadQueue.Abort();
//}
m_userList.Clear();
}
/// <summary>
/// 登录信息在数据库中验证成功后调用
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="sessionID">登录流水号</param>
/// <returns>
/// 0:用户及登录流水号成功保存于队列
/// -1:保存失败
/// </returns>
public static int AddUserToList(string userName, long sessionID)
{
WriteLog.WriteData w = new WriteLog.WriteData();
int ret = 0;
try
{
HashElement hashElt = new HashElement();
hashElt.SessionID = sessionID;
//如果用户已经登录过,则只更新登录流水号及操作时间,否则新加入队列
lock (m_userList.SyncRoot)
{
if (m_userList.ContainsKey(userName))
{
m_userList[userName] = hashElt;
}
else
{
m_userList.Add(userName, hashElt);
}
}
}
catch (Exception exp)
{
//System.Console.Out.WriteLine(exp.StackTrace);
//System.Console.Out.WriteLine(exp.Message);
w.WriteLine(exp.Message + exp.StackTrace, 01);
ret = -1;
}
return ret;
}
/// <summary>
/// 除登录外其他所有功能调用之前首先调用该方法
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="sessionID">登录流水号</param>
/// <returns>
/// 0:验证用户登录成功
/// -1:验证用户登录失败
/// -2:用户未登录
/// -3:用户已重新登录或在别处登录
/// </returns>
public static int CheckUserLogin(string userName, long sessionID)
{
//WriteLog.WriteData w = new WriteLog.WriteData();
int ret = 0;
try
{
lock (m_userList.SyncRoot)
{
if (m_userList.ContainsKey(userName))
{
HashElement hashElt = m_userList[userName] as HashElement;
if (hashElt.SessionID.Equals(sessionID))
{
hashElt.Time = DateTime.Now;
m_userList[userName] = hashElt;
ret = 0;
}
else
{
ret = -3;
}
}
else
{
ret = -2;
}
}
}
catch
{
//w.WriteLine(exp.Message + exp.StackTrace, 02);
//System.Console.Out.WriteLine(exp.StackTrace);
//System.Console.Out.WriteLine(exp.Message);
ret = -1;
}
return ret;
}
/// <summary>
/// 检查保存在队列中的用户在线是否超过时限,该方法供线程调用
/// </summary>
private static void CheckListTO()
{
//WriteLog.WriteData w = new WriteLog.WriteData();
try
{
//保存待清理的超时在线用户的临时队列
List<string> toKeys = new List<string>();
while (true)
{
//线程每隔1分钟执行检查清理操作
Thread.Sleep(1000 * 60);
//遍历保存在线用户的哈希表
lock (m_userList.SyncRoot)
{
foreach (DictionaryEntry deElt in m_userList)
{
//如果有超时的在线用户,将超时用户时放入临时的队列中,
//检查完哈希表之后再进行清理操作
//不能在检查过程中执行哈希表的删除键值操作,否则会出现异常。
HashElement htElt = deElt.Value as HashElement;
if (DateTime.Now - htElt.Time > m_tsSub)
{
toKeys.Add((string)deElt.Key);
}
}
//如果有超时的在线用户则进行清理操作
if (0 < toKeys.Count)
{
foreach (string key in toKeys)
{
m_userList.Remove(key);
}
toKeys.Clear();
}
}
}
}
catch
{
//System.Console.Out.WriteLine(exp.StackTrace);
//System.Console.Out.WriteLine(exp.Message);
//w.WriteLine(exp.Message + exp.StackTrace, 03);
}
}
/// <summary>
/// 获取当前在线用户统计数
/// </summary>
/// <returns>统计数</returns>
public static int GetUserCount()
{
//WriteLog.WriteData w = new WriteLog.WriteData();
int count = 0;
try
{
lock (m_userList.SyncRoot)
{
count = m_userList.Count;
}
}
catch
{
//System.Console.Out.WriteLine(exp.StackTrace);
//System.Console.Out.WriteLine(exp.Message);
//w.WriteLine(exp.Message + exp.StackTrace, 04);
}
return count;
}
}
}
- C#一个存储用户信息的类,支持单点登录
- 关于单点登录中的用户信息存储问题的探讨
- 单点登录CAS6-服务端自定义返回的用户信息
- 基于CAS的单点登录SSO[3]: 改造cas-overlays-template支持Redis存储Ticket
- CAS客户端.NET集成单点登录获取不到登录用户信息的问题
- 登录用户信息持久化存储
- 利用html5的本地存储功能实现登录用户信息保存
- 利用html5的本地存储功能实现登录用户信息保存
- webseal 单点登录的一个问题
- 解决单点登录的一个方法!
- 一个简单的单点登录构思
- 单点登录系统CAS搭建及取得更多用户信息的实现
- 单点登录系统CAS搭建及取得更多用户信息的实现
- Mvc4单点登录之四 配置Cas服务端,返回更多的用户信息!
- c# 实现单点登录
- C# 单点登录 MVC
- 一个四用户信息同步更新的存储过程
- 一个四用户信息同步更新的存储过程
- [转]关于数组的几道面试题
- Android AlarmManager闹钟实现
- ASP.NET—016:ASP.NET中保存文件对话框
- ubuntu停止支持了怎么办?
- [转]网易2013校园招聘笔试题集锦
- C#一个存储用户信息的类,支持单点登录
- CentOS 5 centos 6下安装Axel插件加速yum下载
- 关于typedef的用法总结
- poj 2987 Firing (最大权闭合子图)
- XCode6添加自定义framework运行真机出现dyld: Library not loaded的解决方法
- Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in
- 从一次生产事故说起——linux的单用户模式,救援模式等等
- PHPExcel 基本用法详解
- MapReduce原理分析记录