/// <summary> /// 关闭。 /// </summary> /// <remarks>关闭。</remarks> private void Close() { //锁定会话传输通道列表。 lock (this.SyncRoot) { //声明创建会话传输通道键列表。 List <Guid> keys = new List <Guid>(); //遍历会话传输通道键列表。 foreach (Guid item in this.list.Keys) { //将会话传输通道键添加入列表中。 keys.Add(item); } //遍历全部会话传输通道键。 foreach (Guid item in keys) { //验证会话传输通道是否存在。 if (this.list.ContainsKey(item)) { //获取要删除的会话传输通道对象。 SessionTransferChannel channel = this.list[item]; try { //从会话传输通道列表中删除。 this.list.Remove(item); } finally { //释放会话传输通道资源。 channel.Dispose(); } } } } }
/// <summary> /// 删除会话传输通道。 /// </summary> /// <remarks>删除会话传输通道。</remarks> internal void Remove(Guid key) { //验证要删除的会话传输通道键是否有效。 if (key == Guid.Empty) { return; } //创建线程删除会话传输通道。 new Thread(new ParameterizedThreadStart(delegate(object obj) { //要删除的会话传输通道键。 Guid k = (Guid)obj; //锁定同步。 lock (this.SyncRoot) { //验证会话传输通道是否存在。 if (this.list.ContainsKey(k)) { //获取要删除的会话传输通道对象。 SessionTransferChannel channel = this.list[k]; try { //从会话传输通道列表中删除。 this.list.Remove(k); } finally { //释放会话传输通道资源。 channel.Dispose(); } } } //启动线程。 })).Start(key); }
/// <summary> /// 写入打包对象。 /// </summary> /// <remarks>写入打包对象。</remarks> /// <param name="pack">设置打包对象。</param> internal virtual void Write(WriteStreamPackaging pack) { //刷新打包数据。 pack.Flush(); //声明会话传输通道。 SessionTransferChannel channel = null; try { //获取会话传输通道对象,返回必须是被锁定的会话传输 channel = this.GetChannel(); //验证会话传输通道是否被锁定。 if (!channel.IsLock) #if DEBUG { throw new Exception("获取会话传输通道没有被锁定错误![Key:" + channel.Key.ToString() + "]"); } #else { throw new Exception("获取会话传输通道没有被锁定错误!"); } #endif //重置通道空闲超时计数器。 channel.CurrentChannelTimeoutCounter = 0; //写入数据流。 channel.Stream.Write(pack.GetBuffer, 0, pack.GetBuffer.Length); } finally { //解锁会话传输通道。 channel.UnLock(); } }
/// <summary> /// 读取会话键集合内容。 /// </summary> /// <remarks>读取会话键集合内容。</remarks> /// <param name="channel">设置读取通道对象。</param> /// <param name="itemCollection">设置会话容器键集合对象。</param> private static void ReadItems(SessionTransferChannel channel, SessionStateItemCollection itemCollection) { //声明获取会话存放键集合数量。 #if DEBUG int itemCount = channel.Reader.ReadInt32(); Debug.WriteLine("ReadItems[itemCount:" + itemCount.ToString() + "]", "SessionStore"); //验证要读取的会话容器键集合数量。 if (itemCount > 0) { //遍历循环读取所有键与对象。 for (int i = 0; i < itemCount; i++) { //获取存储数据类型。 SessionStoreDataType dataType = (SessionStoreDataType)channel.Reader.ReadByte(); switch (dataType) { #else for (int i = 0; i < channel.Reader.ReadInt32(); i++) { switch ((SessionStoreDataType)channel.Reader.ReadByte()) { #endif case SessionStoreDataType.Null: //读取空值对象。 itemCollection[channel.ReadString()] = null; break; case SessionStoreDataType.Bool: //读取Bool值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadBoolean(); break; case SessionStoreDataType.Byte: //读取Byte值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadByte(); break; case SessionStoreDataType.SByte: //读取SByte值对象。 itemCollection[channel.ReadString()] = unchecked((sbyte)channel.Reader.ReadByte()); break; case SessionStoreDataType.Short: //读取Short值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadInt16(); break; case SessionStoreDataType.UShort: //读取UShort值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadUInt16(); break; case SessionStoreDataType.Int: //读取Int值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadInt32(); break; case SessionStoreDataType.UInt: //读取UInt值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadUInt32(); break; case SessionStoreDataType.Long: //读取Long值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadInt64(); break; case SessionStoreDataType.ULong: //读取ULong值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadUInt64(); break; case SessionStoreDataType.Float: //读取Float值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadSingle(); break; case SessionStoreDataType.Decimal: //读取Decimal值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadDecimal(); break; case SessionStoreDataType.Double: //读取Double值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadDouble(); break; case SessionStoreDataType.String: //读取String值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadString(); break; case SessionStoreDataType.Guid: //读取Guid值对象。 itemCollection[channel.ReadString()] = channel.ReadGuid(); break; case SessionStoreDataType.Buffer: //读取Buffer值对象。 itemCollection[channel.ReadString()] = channel.ReadBytes(); break; case SessionStoreDataType.DateTime: //读取DateTime值对象。 itemCollection[channel.ReadString()] = channel.ReadDateTime(); break; case SessionStoreDataType.TimeSpan: //读取TimeSpan值对象。 itemCollection[channel.ReadString()] = channel.ReadTimeSpan(); break; case SessionStoreDataType.Object: //读取Object值对象。 itemCollection[channel.ReadString()] = channel.ReadObject(); break; case SessionStoreDataType.Icon: //读取Icon值对象。 using (MemoryStream outms = new MemoryStream(channel.ReadBytes())) { itemCollection[channel.ReadString()] = new Icon(outms); } break; case SessionStoreDataType.Image: //读取Image值对象。 using (MemoryStream outms = new MemoryStream(channel.ReadBytes())) { itemCollection[channel.ReadString()] = new Bitmap(outms); } break; case SessionStoreDataType.Char: //读取Char值对象。 itemCollection[channel.ReadString()] = channel.Reader.ReadChar(); break; case SessionStoreDataType.Chars: //读取Chars值对象。 itemCollection[channel.ReadString()] = channel.ReadChars(); break; } } #if DEBUG } #endif }
/// <summary> /// 从会话数据存储区中返回只读会话状态数据。 /// </summary> /// <remarks>从会话数据存储区中返回只读会话状态数据。</remarks> /// <param name="lockRecord">锁记录。</param> /// <param name="context">当前请求的 HttpContext。</param> /// <param name="id">当前请求的 SessionID。</param> /// <param name="locked">当此方法返回时,如果请求的会话项在会话数据存储区被锁定,请包含一个设置为 true 的布尔值;否则请包含一个设置为 false 的布尔值。</param> /// <param name="lockAge">当此方法返回时,请包含一个设置为会话数据存储区中的项锁定时间的 TimeSpan 对象。</param> /// <param name="lockId">当此方法返回时,请包含一个设置为当前请求的锁定标识符的对象。有关锁定标识符的详细信息,请参见 SessionStateStoreProviderBase 类摘要中的“锁定会话存储区数据”。</param> /// <param name="actions">当此方法返回时,请包含 SessionStateActions 值之一,指示当前会话是否为未初始化的无 Cookie 会话。</param> /// <returns>使用会话数据存储区中的会话值和信息填充的 SessionStateStoreData。</returns> private SessionStateStoreData GetSessionStoreItem(bool lockRecord, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { Debug.WriteLine("GetSessionStoreItem[锁记录:" + lockRecord.ToString() + ",会话id:" + (id == null ? "null" : id) + "]", "SessionStore"); //声明 //会话容器 SessionStateStoreData item = null; //锁定时间 lockAge = TimeSpan.Zero; //锁定Id lockId = null; //锁定 locked = false; //动作 actions = 0; //过期 DateTime expires; //找到记录 bool foundRecord = false; //返回过期删除 bool deleteData = false; //超时时间 int timeout = 0; //创建会话数据集合。 SessionStateItemCollection ic = new SessionStateItemCollection(); //声明会话传输通道。 SessionTransferChannel channel = null; try { //获取会话传输通道对象,返回必须是被锁定的会话传输 channel = this.ChannelManager.GetChannel(); if (!channel.IsLock) #if DEBUG throw new Exception("获取会话传输通道没有被锁定错误![Key:" + channel.Key.ToString() + "]"); #else throw new Exception("获取会话传输通道没有被锁定错误!"); #endif // channel.Write(new object[] { //指令 (byte)SessionStoreCommandHeader.GetItemExclusive, //会话Id id, //锁记录 lockRecord }); //锁记录。 if (lockRecord) { channel.Write(new object[] { //锁定 true, //锁定时间 DateTime.Now, //过期时间 DateTime.Now, }); //读取锁状态。 if (!channel.Reader.ReadBoolean()) //没有记录被更新,因为记录被锁定或没有找到。 locked = true; else //记录已更新。 locked = false; } // if (channel.Reader.ReadBoolean()) { //过期 expires = channel.ReadDateTime(); //验证是否过期 if (expires < DateTime.Now) { //该纪录是过期。将其标记为未锁定。 locked = false; //会话已过期。标记为删除的数据。 deleteData = true; } else //未过期 foundRecord = true; //锁定Id lockId = channel.Reader.ReadInt32(); //锁定经过时间 lockAge = channel.ReadTimeSpan(); //动作 actions = (SessionStateActions)channel.Reader.ReadInt32(); //超时 timeout = channel.Reader.ReadInt32(); //读取集合数据。 ReadItems(channel, ic); } //创建写入流打包对象。 WriteStreamPackaging pack = channel.CreateWriteStreamPackaging(false); //是否删除 pack.Write(deleteData); //记录没有被发现。确保锁定的是假的。 if (!foundRecord) //没有锁定 locked = false; //如果记录被发现,你获得了锁,然后设置 //锁定,清除actionFlags, //并创建SessionStateStoreItem返回。 if (foundRecord && !locked) { //累加锁定Id lockId = (int)lockId + 1; //锁定 pack.Write(true); //锁定Id pack.Write((int)lockId); //如果动作Flags参数未初始化项目。 //反序列化存储SessionStateItemCollection。 if (actions == SessionStateActions.InitializeItem) { item = new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), this.SessionStateConfig.Timeout.Minutes); } else { item = new SessionStateStoreData(ic, SessionStateUtility.GetSessionStaticObjects(context), this.SessionStateConfig.Timeout.Minutes); } } else { //没有锁定 pack.Write(false); } pack.Flush(channel.Stream); } finally { channel.UnLock(); } return item; }
/// <summary> /// 获取会话传输通道。 /// </summary> /// <remarks>获取会话传输通道。</remarks> /// <returns>SessionsStore.SessionTransferChannel</returns> internal SessionTransferChannel GetChannel() { //重新开始等待可用的会话传输通道。 Restart: //锁定会话传输通道列表。 lock (this.SyncRoot) { //验证释放有可用未被锁定的会话传输通道。 if (this.list.Count > this.LockCount()) { //遍历全部会话传输通道对象。 foreach (SessionTransferChannel item in this.list.Values) { //锁定会话传输通道。 if (item.Lock()) { Debug.WriteLine("找到可以用的通道获取它[Key:" + item.Key.ToString() + "]", "SessionTransferChannelManager.GetChannel"); //得到被有效锁定的会话传输通道。 return(item); } } } } //验证是否有最大会话传输通道限制。 if (this.Owner.MaxSessionTransferChannel > 0) { //声明会话传输通道数量。 int n = this.Count; //验证会话传输通道是否已经在最大数量。 if (n >= this.Owner.MaxSessionTransferChannel) { //会话传输通道已经在最大数量不允许再创建新的会话传输通道。 goto Restart; } } //创建新的会话传输通道。 SessionTransferChannel channel = null; try { //新建会话传输通道对象。 channel = this.CreateChannel(); //连接到会话中心。 channel.Connection(); //锁定会话传输通道对象。 channel.Lock(); //将新建的会话传输通道添加到会话传输通道列表中。 this.list.Add(channel.Key, channel); } catch (Exception e) { //验证通道对象是否为空。 if (channel != null) { //在通道列表中删除当前通道。 if (this.list.ContainsKey(channel.Key)) { this.list.Remove(channel.Key); } //是否通道资源。 try { channel.Dispose(); } finally { channel = null; } } throw e; } return(channel); }
/// <summary> /// 连接到全局会话中心。 /// </summary> /// <remarks>连接到全局会话中心。</remarks> internal void Connection() { //锁定会话传输通道管理对象。 lock (this.SyncRoot) { //声明会话传输通道。 SessionTransferChannel channel = null; try { //创建会话传输通道。 channel = this.CreateChannel(); //锁定通道。 lock (channel.SyncRoot) { //锁定。 channel.Lock(); //连接到全局会话中心。 channel.Connection(); //将会话传输通道添加入列表中。 this.list.Add(channel.Key, channel); //发送初始化指令。 channel.Write(new object[] { (byte)SessionStoreCommandHeader.Initialize, (byte)SessionTransferNodeTypes.ASP_NET_FORM }); //初始化会话传输字符编码。 #if DEBUG byte ed = channel.Reader.ReadByte(); Debug.WriteLine("Connection[CharacterEncoding:" + ed.ToString() + "]", "SessionTransferChannelManager"); switch ((CharacterEncoding)ed) #else switch ((CharacterEncoding)channel.Reader.ReadByte()) #endif { case CharacterEncoding.UTF8Encoding: this.Owner.Encoding = System.Text.Encoding.UTF8; break; case CharacterEncoding.UTF7Encoding: this.Owner.Encoding = System.Text.Encoding.UTF7; break; case CharacterEncoding.UTF32Encoding: this.Owner.Encoding = System.Text.Encoding.UTF32; break; case CharacterEncoding.UnicodeEncoding: this.Owner.Encoding = System.Text.Encoding.Unicode; break; case CharacterEncoding.ASCIIEncoding: this.Owner.Encoding = System.Text.Encoding.ASCII; break; case CharacterEncoding.BigEndianUnicode: this.Owner.Encoding = System.Text.Encoding.BigEndianUnicode; break; } //初始化获取全局会话中心当前时间。 this.Owner.SessionCenterCurrentDateTime = channel.ReadDateTime(); Debug.WriteLine("Connection[SessionCenterCurrentDateTime:" + this.Owner.SessionCenterCurrentDateTime.ToString() + "]", "SessionTransferChannelManager"); //初始化获取全局会话中心通道最大限制。 int MaxSessionTransferChannel = channel.Reader.ReadInt32(); if (MaxSessionTransferChannel > 0) { this.Owner.MaxSessionTransferChannel = MaxSessionTransferChannel; } Debug.WriteLine("Connection[MaxSessionTransferChannel:" + this.Owner.MaxSessionTransferChannel.ToString() + "]", "SessionTransferChannelManager"); //发送安全连接内容。 if (string.IsNullOrEmpty(this.Owner.SessionCenterSecureConnectionContent)) { channel.Writer.Write((int)0); Debug.WriteLine("Connection[SessionCenterSecureConnectionContent:" + (this.Owner.SessionCenterSecureConnectionContent == null ? "null" : this.Owner.SessionCenterSecureConnectionContent) + "]", "SessionTransferChannelManager"); } else { byte[] bytes = new byte[this.Owner.Encoding.GetByteCount(this.Owner.SessionCenterSecureConnectionContent)]; Buffer.BlockCopy(BitConverter.GetBytes(bytes.Length), 0, bytes, 0, TypeLengthConstant.IntLength); Buffer.BlockCopy(this.Owner.Encoding.GetBytes(this.Owner.SessionCenterSecureConnectionContent), 0, bytes, TypeLengthConstant.IntLength, bytes.Length); channel.Writer.Write(bytes); Debug.WriteLine("Connection[SessionCenterSecureConnectionContent:" + this.Owner.SessionCenterSecureConnectionContent + "]", "SessionTransferChannelManager"); } //验证安全连接是否通过。 #if DEBUG if (channel.Reader.ReadBoolean()) { Debug.WriteLine("Connection[安全连接验证通过]", "SessionTransferChannelManager"); } else { Debug.WriteLine("Connection[安全连接验证不通过]", "SessionTransferChannelManager"); throw new Exception("安全连接验证不通过!"); } #else if (!channel.Reader.ReadBoolean()) { throw new Exception("安全连接验证不通过!"); } #endif } } catch (Exception e) { Debug.WriteLine("Connection[e:" + e.ToString() + "]", "SessionTransferChannelManager"); //验证通道对象是否为空。 if (channel != null) { //在通道列表中删除当前通道。 if (this.list.ContainsKey(channel.Key)) { this.list.Remove(channel.Key); } //是否通道资源。 try { channel.Dispose(); } finally { channel = null; } } throw e; } finally { //解锁。 if (channel != null) { channel.UnLock(); } } } }