こんばんは。
今夜は Azure のセッションについて調べてみた。
調べていて、良いまとめサイトがあったので紹介します。
ブチザッキ - {2011/08/23} Windows AzureのWeb Roleでセッションを共有する
http://buchizo.wordpress.com/2011/08/23/windows-azure%E3%81%AEweb-role%E3%81%A7%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E5%85%B1%E6%9C%89%E3%81%99%E3%82%8B/
では今夜はこのへんで…
ごめんなさい。
以上の記事に書かれていることで、だいたいのセッションの問題は解決すると思いうけど、
あるものを使うだけでは面白くないため、今回から自前でセッション管理してみようとおもいます。
まず、簡単なカスタムセッションを作ってみます。
SessionStateStoreProviderBase クラスを継承して作っていくようです。
http://msdn.microsoft.com/ja-jp/library/ms178587%28v=VS.90%29.aspx
サンプルはMSDNにもあるのでそれをみつつ…
http://msdn.microsoft.com/ja-jp/library/ms178588%28v=VS.90%29.aspx
http://msdn.microsoft.com/ja-jp/library/ms178589%28v=VS.90%29.aspx
public class TestSessionStateProvider : System.Web.SessionState.SessionStateStoreProviderBase {
private int Timeout {
get { return 20; }
}
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) {
base.Initialize(name, config);
}
public override void InitializeRequest(HttpContext context) {
}
public override void EndRequest(HttpContext context) {
}
public override void Dispose() {
}
public override System.Web.SessionState.SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out System.Web.SessionState.SessionStateActions actions) {
return GetSessionData(true, context, id, out locked, out lockAge, out lockId, out actions);
}
public override System.Web.SessionState.SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out System.Web.SessionState.SessionStateActions actions) {
return GetSessionData(false, context, id, out locked, out lockAge, out lockId, out actions);
}
public override void SetAndReleaseItemExclusive(HttpContext context, string id, System.Web.SessionState.SessionStateStoreData item, object lockId, bool newItem) {
UpdateSessionData(context, id, item, lockId, newItem);
}
public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) {
// 実装は後ほど
}
public override void RemoveItem(HttpContext context, string id, object lockId, System.Web.SessionState.SessionStateStoreData item) {
// 実装は後ほど
}
public override void CreateUninitializedItem(HttpContext context, string id, int timeout) {
// 実装は後ほど
}
public override System.Web.SessionState.SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout) {
return new SessionStateStoreData(new SessionStateItemCollection(),
SessionStateUtility.GetSessionStaticObjects(context),
timeout);
}
public override bool SetItemExpireCallback(System.Web.SessionState.SessionStateItemExpireCallback expireCallback) {
// 実装は後ほど
return false;
}
public override void ResetItemTimeout(HttpContext context, string id) {
// 実装は後ほど
}
private SessionStateStoreData GetSessionData(bool lockSession, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out System.Web.SessionState.SessionStateActions actions) {
// 今回は、HttpContext.Application にセッション情報を保存する
SessionStateStoreData sessionState;
Dictionary<string, byte[]> sessionData
= (Dictionary<string, byte[]>)HttpContext.Current.Application["session"];
// id のセッションがあるか
if ( sessionData != null && sessionData.ContainsKey(id) ) {
// セッションを復元
using ( var stream = new MemoryStream(sessionData[id]) ) {
using ( var reader = new BinaryReader(stream) ) {
sessionState = new SessionStateStoreData(SessionStateItemCollection.Deserialize(reader),
SessionStateUtility.GetSessionStaticObjects(context),
this.Timeout);
}
}
} else {
// 新規にセッションを作成
sessionState = CreateNewStoreData(context, this.Timeout);
}
locked = false;
lockId = null;
lockAge = new TimeSpan(0, this.Timeout, 0);
actions = SessionStateActions.None;
return sessionState;
}
private void UpdateSessionData(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) {
// HttpContext.Application に保存されているセッション情報を復元する
Dictionary<string, byte[]> sessionData
= (Dictionary<string, byte[]>)HttpContext.Current.Application["session"];
if ( sessionData == null ) {
sessionData = new Dictionary<string, byte[]>();
}
using ( var stream = new MemoryStream() ) {
using ( var writer = new BinaryWriter(stream) ) {
var sessionItem = (SessionStateItemCollection)item.Items;
sessionItem.Serialize(writer);
}
sessionData[id] = stream.GetBuffer();
}
HttpContext.Current.Application["session"] = sessionData;
}
}
ただ HttpContext.Application に保存するだけのものです。
(InProc セッションの超劣化版)
これから少しずつまともに使えるものにしていこう。