/// <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="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> 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(); } } } }