實事求是專怼捞頭 發表於 2013-8-28 23:46:00

基于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)">&lt;?</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)">?&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">MongoDBSession</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">DbName</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>SessionDB<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">DbName</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>mongodb://localhost<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">IdentityMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">MongoDBSession</span><span style="color: rgba(0, 0, 255, 1)">&gt;</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)">&lt;br /&gt;</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)">&lt;br /&gt;</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)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">system.web</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</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)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">providers</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</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)">/&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">providers</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">sessionState</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">system.web</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>这里会牵扯出2个类:</p>
<ol>
<li>A2DFramework.SessionService.MongoDBSessionIDManager</li>
<li>A2DFramework.SessionService.MongoDBSessionStateStore</li>
</ol>
<p>&nbsp;<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>&nbsp;</p>
</li>
</ul>
<p>&nbsp;<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>&lt;MongoDBSessionEntity&gt; 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&lt;MongoDBSessionEntity&gt; 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&lt;MongoDBSessionEntity&gt; 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&lt;MongoDBSessionEntity&gt; 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>&lt;MongoDBSessionEntity&gt; 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>&lt;MongoDBSessionEntity&gt; 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 &lt;<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 &amp;&amp; !<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>&nbsp;</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&lt;MongoDBSessionEntity&gt; 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>&lt;MongoDBSessionEntity&gt; collection = db.GetCollection&lt;MongoDBSessionEntity&gt;<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>&nbsp;</p>
<p>&nbsp;<span style="color: rgba(255, 0, 0, 1); font-size: 18px">运行效果:</span></p>
<p>&nbsp;<img src="//images0.cnblogs.com/blog/68230/201308/28233658-159af63324d442b9a401a203bb69aba7.png" alt=""></p>
<p>&nbsp;<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>&nbsp;<img src="//images0.cnblogs.com/blog/68230/201308/28234000-84fc4dbd6bb54d25b457511b74f8f82d.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;源代码已经更新到A2D Framework中了。</p>
<p>&nbsp;</p>
<p>&nbsp;</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]
查看完整版本: 基于MongoDB打造.Net的分布式Session子系统