基于MongoDB打造.Net的分布式Session子系统
<p><span style="color: rgba(255, 0, 0, 1)">Taobao有她自己的分布式session框架,.net阵营也不能落后了,在下做了个基于MongoDB的支持最多26台MongoDB的分布式Session框架。</span></p><p>先看看配置文件:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><?</span><span style="color: rgba(255, 0, 255, 1)">xml version="1.0" encoding="utf-8" </span><span style="color: rgba(0, 0, 255, 1)">?></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">MongoDBSession</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">DbName</span><span style="color: rgba(0, 0, 255, 1)">></span>SessionDB<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">DbName</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="A"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="B"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="C"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="D"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="E"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="F"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="G"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="H"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="I"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="J"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="K"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="L"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="M"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="N"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="O"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="P"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="Q"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="R"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="S"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="T"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="U"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="V"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="W"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="X"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="Y"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap </span><span style="color: rgba(255, 0, 0, 1)">Identity</span><span style="color: rgba(0, 0, 255, 1)">="Z"</span><span style="color: rgba(0, 0, 255, 1)">></span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">MongoDBSession</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p>从Identity A一直到Z,默认分成了26个Map,具体的C#应用代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span> btnTest_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
Session[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">A</span><span style="color: rgba(128, 0, 0, 1)">"</span>] =<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now;
Session[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">B</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = <span style="color: rgba(128, 0, 128, 1)">1111111111111</span><span style="color: rgba(0, 0, 0, 1)">;
Session[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C</span><span style="color: rgba(128, 0, 0, 1)">"</span>] = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fffffffffffffff</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span> btnGetSession_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
Response.Write(Session[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">A</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">].ToString());
Response.Write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)"><br /></span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Response.Write(Session[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">B</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">].ToString());
Response.Write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)"><br /></span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
Response.Write(Session[</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">].ToString());
}
</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span> btnAbandon_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
Session.Abandon();
}</span></pre>
</div>
<p>呵呵,就是普通的Session用法。</p>
<p>这个要配置web.config:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">system.web</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">sessionState </span><span style="color: rgba(255, 0, 0, 1)">mode</span><span style="color: rgba(0, 0, 255, 1)">="Custom"</span><span style="color: rgba(255, 0, 0, 1)"> customProvider</span><span style="color: rgba(0, 0, 255, 1)">="A2DSessionProvider"</span><span style="color: rgba(255, 0, 0, 1)"> sessionIDManagerType</span><span style="color: rgba(0, 0, 255, 1)">="A2DFramework.SessionService.MongoDBSessionIDManager"</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">providers</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">add </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="A2DSessionProvider"</span><span style="color: rgba(255, 0, 0, 1)"> type</span><span style="color: rgba(0, 0, 255, 1)">="A2DFramework.SessionService.MongoDBSessionStateStore"</span><span style="color: rgba(0, 0, 255, 1)">/></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">providers</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">sessionState</span><span style="color: rgba(0, 0, 255, 1)">></span>
<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">system.web</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p>这里会牵扯出2个类:</p>
<ol>
<li>A2DFramework.SessionService.MongoDBSessionIDManager</li>
<li>A2DFramework.SessionService.MongoDBSessionStateStore</li>
</ol>
<p> <strong><span style="color: rgba(255, 0, 0, 1)">MongoDBSessionIDManager</span></strong></p>
<ul>
<li>自定义生成的cookie值(也就是SessionID),在这个sample中,会生成如“E.asadfalkasdfjal”这样的SessionID,其中前缀E代表这个Session的信息会映射到哪台MongoDB上。</li>
<li>关键代码</li>
<li>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MongoDBSessionIDManager : SessionIDManager
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> Random rnd = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Random();
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">object</span> oLock = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> CreateSessionID(System.Web.HttpContext context)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> index = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">lock</span>(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.oLock)
{
index </span>=<span style="color: rgba(0, 0, 0, 1)"> rnd.Next(SessionConfiguration.SessionServerIdentities.Length);
}
</span><span style="color: rgba(0, 0, 255, 1)">string</span> sessionId = <span style="color: rgba(0, 0, 255, 1)">string</span>.Format(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{0}.{1}</span><span style="color: rgba(128, 0, 0, 1)">"</span>, SessionConfiguration.SessionServerIdentities, <span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">.CreateSessionID(context));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> sessionId;
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">string</span> Encode(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> DESEncryptor.Encode(id, SessionConfiguration.DESKey);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">string</span> Decode(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> DESEncryptor.Decode(id, SessionConfiguration.DESKey);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Validate(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> prefix;
</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> realId;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!Helper.ParseSessionID(id, <span style="color: rgba(0, 0, 255, 1)">out</span> prefix, <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> realId))
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">.Validate(realId);
}
}</span></pre>
</div>
<p> </p>
</li>
</ul>
<p> <span style="color: rgba(255, 0, 0, 1)"><strong>MongoDBSessionStateStore</strong></span></p>
<ul>
<li>自定义Session过程中最核心的一个类,代码如下(较多):</li>
<li>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">sealed</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MongoDBSessionStateStore : SessionStateStoreProviderBase
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> SessionStateSection pConfig;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> pApplicationName;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Initialize(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> name, System.Collections.Specialized.NameValueCollection config)
{
</span><span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">.Initialize(name, config);
pApplicationName </span>=<span style="color: rgba(0, 0, 0, 1)">System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
System.Configuration.Configuration cfg </span>=<span style="color: rgba(0, 0, 0, 1)"> WebConfigurationManager.OpenWebConfiguration(pApplicationName);
pConfig </span>=(SessionStateSection)cfg.GetSection(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">system.web/sessionState</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> SessionStateStoreData CreateNewStoreData(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> timeout)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> SessionStateStoreData(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span> CreateUninitializedItem(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">string</span> id, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> timeout)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">insert to db</span>
MongoDBSessionEntity session = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MongoDBSessionEntity();
session.ApplicationName </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.pApplicationName;
session.SessionId </span>=<span style="color: rgba(0, 0, 0, 1)"> id;
session.Created </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now;
session.Expires </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now.AddMinutes(pConfig.Timeout.Minutes);
session.LockDate </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now;
session.LockId </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
session.Timeout </span>=<span style="color: rgba(0, 0, 0, 1)"> timeout;
session.Locked </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
session.Flags </span>= (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)SessionStateActions.InitializeItem;
MongoCollection</span><MongoDBSessionEntity> collection =<span style="color: rgba(0, 0, 0, 1)"> Helper.GetMongoDBCollection(id);
collection.Save(session);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Dispose()
{
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> EndRequest(System.Web.HttpContext context)
{
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> SessionStateStoreData GetItem(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">string</span> id, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> locked, <span style="color: rgba(0, 0, 255, 1)">out</span> TimeSpan lockAge, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">object</span> lockId, <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> SessionStateActions actions)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> GetSessionStoreItem(<span style="color: rgba(0, 0, 255, 1)">false</span>, context, id, <span style="color: rgba(0, 0, 255, 1)">out</span> locked, <span style="color: rgba(0, 0, 255, 1)">out</span> lockAge, <span style="color: rgba(0, 0, 255, 1)">out</span> lockId, <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> actions);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> SessionStateStoreData GetItemExclusive(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">string</span> id, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> locked, <span style="color: rgba(0, 0, 255, 1)">out</span> TimeSpan lockAge, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">object</span> lockId, <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> SessionStateActions actions)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> GetSessionStoreItem(<span style="color: rgba(0, 0, 255, 1)">true</span>, context, id, <span style="color: rgba(0, 0, 255, 1)">out</span> locked, <span style="color: rgba(0, 0, 255, 1)">out</span> lockAge, <span style="color: rgba(0, 0, 255, 1)">out</span> lockId, <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> actions);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> InitializeRequest(System.Web.HttpContext context)
{
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ReleaseItemExclusive(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">string</span> id, <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> lockId)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">update locked=0, expired=, where lockId=?</span>
MongoCollection<MongoDBSessionEntity> collection =<span style="color: rgba(0, 0, 0, 1)"> Helper.GetMongoDBCollection(id);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> query = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LockId</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">.Parse(lockId.ToString())),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName));
</span><span style="color: rgba(0, 0, 255, 1)">var</span> update = Update.Set(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Locked</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)
.Set(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Expires</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.Now.AddMinutes(pConfig.Timeout.Minutes));
collection.Update(query, update);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span> RemoveItem(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">string</span> id, <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> lockId, SessionStateStoreData item)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">delete where sessionId=? and lockId=? and applicationname=?</span>
MongoCollection<MongoDBSessionEntity> collection =<span style="color: rgba(0, 0, 0, 1)"> Helper.GetMongoDBCollection(id);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> query = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LockId</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">.Parse(lockId.ToString())),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName));
collection.Remove(query);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ResetItemTimeout(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">update expire date</span>
MongoCollection<MongoDBSessionEntity> collection =<span style="color: rgba(0, 0, 0, 1)"> Helper.GetMongoDBCollection(id);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> query = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName));
</span><span style="color: rgba(0, 0, 255, 1)">var</span> update = Update.Set(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Expires</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.Now.AddMinutes(pConfig.Timeout.Minutes));
collection.Update(query, update);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetAndReleaseItemExclusive(System.Web.HttpContext context, <span style="color: rgba(0, 0, 255, 1)">string</span> id, SessionStateStoreData item, <span style="color: rgba(0, 0, 255, 1)">object</span> lockId, <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> newItem)
{
MongoCollection</span><MongoDBSessionEntity> collection =<span style="color: rgba(0, 0, 0, 1)"> Helper.GetMongoDBCollection(id);
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (newItem)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">delete expired items</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> query = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName),
Query.LT(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Expires</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.Now));
collection.Remove(query);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">insert new item</span>
MongoDBSessionEntity session = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MongoDBSessionEntity();
session.ApplicationName </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.pApplicationName;
session.SessionId </span>=<span style="color: rgba(0, 0, 0, 1)"> id;
session.Created </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now;
session.Expires </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now.AddMinutes(pConfig.Timeout.Minutes);
session.LockDate </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now;
session.LockId </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
session.Timeout </span>=<span style="color: rgba(0, 0, 0, 1)"> item.Timeout;
session.Locked </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
session.Flags </span>= (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)SessionStateActions.None;
session.SessionItems </span>=<span style="color: rgba(0, 0, 0, 1)"> Helper.Serialize((SessionStateItemCollection)item.Items);
collection.Save(session);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">update item</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> query = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LockId</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">.Parse(lockId.ToString())));
MongoDBSessionEntity entity</span>=<span style="color: rgba(0, 0, 0, 1)"> collection.FindOne(query);
entity.Expires </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now.AddMinutes(item.Timeout);
entity.SessionItems </span>=<span style="color: rgba(0, 0, 0, 1)"> Helper.Serialize((SessionStateItemCollection)item.Items);
entity.Locked </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
collection.Save(entity);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> SessionStateStoreData GetSessionStoreItem(<span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> lockRecord, System.Web.HttpContext context,
</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id,
</span><span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> locked,
</span><span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> TimeSpan lockAge,
</span><span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> lockId,
</span><span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)"> SessionStateActions actions)
{
SessionStateStoreData item </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
lockAge </span>=<span style="color: rgba(0, 0, 0, 1)"> TimeSpan.Zero;
lockId </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
locked </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
actions </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> foundRecord = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> deleteData = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
MongoCollection</span><MongoDBSessionEntity> collection =<span style="color: rgba(0, 0, 0, 1)"> Helper.GetMongoDBCollection(id);
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (lockRecord)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">update db, set locked=1, lockdate=now</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> query1 = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Locked</span><span style="color: rgba(128, 0, 0, 1)">"</span>, MongoDB.Bson.BsonValue.Create(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">)),
Query.GT(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Expires</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.UtcNow));
</span><span style="color: rgba(0, 0, 255, 1)">long</span> count =<span style="color: rgba(0, 0, 0, 1)"> collection.Find(query1).Count();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (count == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
locked </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> update = Update.Set(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Locked</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">true</span>).Set(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LockDate</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, DateTime.Now);
collection.Update(query1, update);
locked </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">get item by id</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> query2 = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName));
MongoDBSessionEntity entity</span>=<span style="color: rgba(0, 0, 0, 1)">collection.FindOne(query2);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (entity != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (entity.Expires <<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now)
{
locked </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
deleteData </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
foundRecord </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">delete item if session expired</span>
<span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (deleteData)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> query3 = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName));
collection.Remove(query3);
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">foundRecord)
locked </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (foundRecord && !<span style="color: rgba(0, 0, 0, 1)">locked)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (lockId == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
lockId </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
lockId </span>= (<span style="color: rgba(0, 0, 255, 1)">int</span>)lockId + <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> query4 = Query.And(Query.EQ(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id),
Query.EQ(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">ApplicationName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, pApplicationName));
</span><span style="color: rgba(0, 0, 255, 1)">var</span> update4 = Update.Set(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LockId</span><span style="color: rgba(128, 0, 0, 1)">"</span>, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)lockId)
.Set(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Flags</span><span style="color: rgba(128, 0, 0, 1)">"</span>, (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)SessionStateActions.None);
collection.Update(query4, update4);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (actions ==<span style="color: rgba(0, 0, 0, 1)"> SessionStateActions.InitializeItem)
item </span>=<span style="color: rgba(0, 0, 0, 1)"> CreateNewStoreData(context, pConfig.Timeout.Minutes);
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
item </span>=<span style="color: rgba(0, 0, 0, 1)"> Helper.Deserialize(context, entity.SessionItems, entity.Timeout);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> item;
}
}</span></pre>
</div>
<p> </p>
</li>
</ul>
<p>由于很多方法会用到MongoCollection,因此写了个static公用函数,如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> MongoCollection<MongoDBSessionEntity> GetMongoDBCollection(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> sessionId)
{
IPartitionResolver resolver </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MongoDBSessionPartitionResolver();
</span><span style="color: rgba(0, 0, 255, 1)">string</span> mongoDbConnectionString =<span style="color: rgba(0, 0, 0, 1)"> resolver.ResolvePartition(sessionId);
MongoClient client </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MongoClient(mongoDbConnectionString);
MongoServer srv </span>=<span style="color: rgba(0, 0, 0, 1)"> client.GetServer();
MongoDatabase db </span>=<span style="color: rgba(0, 0, 0, 1)"> srv.GetDatabase(SessionConfiguration.MongoDBName);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">db.CollectionExists(SessionConfiguration.MongoDBCollectionName))
db.CreateCollection(SessionConfiguration.MongoDBCollectionName);
MongoCollection</span><MongoDBSessionEntity> collection = db.GetCollection<MongoDBSessionEntity><span style="color: rgba(0, 0, 0, 1)">(SessionConfiguration.MongoDBCollectionName);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> collection;
}</span></pre>
</div>
<p> </p>
<p> <span style="color: rgba(255, 0, 0, 1); font-size: 18px">运行效果:</span></p>
<p> <img src="//images0.cnblogs.com/blog/68230/201308/28233658-159af63324d442b9a401a203bb69aba7.png" alt=""></p>
<p> <strong>点击Set Session后:</strong></p>
<p><img src="//images0.cnblogs.com/blog/68230/201308/28233816-34af54e971834c55a23236c457020395.png" alt=""></p>
<p><strong>点击Get Session后:</strong></p>
<p><img src="//images0.cnblogs.com/blog/68230/201308/28233913-d17176f4aeae451197d5cd77740ba425.png" alt=""></p>
<p><strong>点击Abandon后:</strong></p>
<p> <img src="//images0.cnblogs.com/blog/68230/201308/28234000-84fc4dbd6bb54d25b457511b74f8f82d.png" alt=""></p>
<p> </p>
<p> 源代码已经更新到A2D Framework中了。</p>
<p> </p>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
自省推动进步,视野决定未来。<br>
心怀远大理想。<br>
为了家庭幸福而努力。<br>
商业合作请看此处:https://www.magicube.ai<br><br>
来源:https://www.cnblogs.com/aarond/p/MongoSession.html
頁:
[1]