1. 程式人生 > >使用StateServer儲存Session,解決Session過期問題

使用StateServer儲存Session,解決Session過期問題

 

    正常操作情況下Session會無故丟失。因為程式是在不停的被操作,排除Session超時的可能。另外,Session超時時間被設定成60分鐘,不會這麼快就超時的。      
  
這次到CSDN上搜了一下帖子,發現好多人在討論這個問題,然後我又google了一下,發現微軟網站上也有類似的內容。  

   現在我就把原因和解決辦法寫出來。       

  

原因:  

   由於Asp.net程式是預設配置,所以Web.Config檔案中關於Session的設定如下:  
   <sessionState    mode='InProc'    stateConnectionString='tcpip=127.0.0.1:42424'    sqlConnectionString='data    source=127.0.0.1;Trusted_Connection=yes'    cookieless='true'    timeout='60'/>  

   我們會發現sessionState標籤中有個屬性mode,它可以有3種取值:InProcStateServer?SQLServer(大小寫敏感)    。預設情況下是InProc,也就是將Session儲存在程序內(IIS5aspnet_wp.exe,而IIS6W3wp.exe),這個程序不穩定,在某些事件發生時,程序會重起,所以造成了儲存在該程序內的Session丟失。  

   哪些情況下該程序會重起呢?微軟的一篇文章告訴了我們:  

 1、配置檔案中processModel

標籤的memoryLimit屬性  

   2Global.asax或者Web.config檔案被更改  

   3Bin資料夾中的Web程式(DLL)被修改  

   4、防毒軟體掃描了一些.config檔案。  

   更多的資訊請參考PRB:    Session    variables    are    lost    intermittently    in    ASP.NET    applications  

   解決辦法: 

   前面說到的sessionState標籤中mode屬性可以有三個取值,除了InProc之外,還可以為StateServerSQLServer。這兩種存Session的方法都是程序外的,所以當aspnet_wp.exe重起的時候,不會影響到Session  

  現在請將mode設定為StateServerStateServer是本機的一個服務,可以在系統服務裡看到服務名為ASP.NET    State    Service的服務,預設情況是不啟動的。當我們設定modeStateServer之後,請手工將該服務啟動。  

   這樣,我們就能利用本機的StateService來儲存Session了,除非電腦重啟或者StateService崩掉,否則Session是不會丟的(因Session超時被丟棄是正常的)。  

   除此之外,我們還可以將Session通過其他電腦的StateService來儲存。具體的修改是這樣的。同樣還在sessionState標籤中,有個stateConnectionString='tcpip=127.0.0.1:42424'屬性,其中有個ip地址,預設為本機(127.0.0.1),你可以將其改成你所知的運行了StateService服務的電腦IP,這樣就可以實現位於不同電腦上的Asp.net程式互通 Session了。  

   如果你有更高的要求,需要在服務期重啟時Session也不丟失,可以考慮將mode設定成SQLServer,同樣需要修改sqlConnectionString屬性。關於使用SQLServer儲存Session的操作,請訪問這裡。

   在使用StateServer或者SQLServer儲存Session時,所有需要儲存到Session的物件除了基本資料型別(預設的資料型別,如 intstring等)外,都必須序列化。只需將[Serializable]標籤放到要序列化的類前就可以了。  

   如:  
   [Serializable]  
   public    class    MyClass  
   {         ......      }  
  
具體的序列化相關的知識請參這裡。     

   至此,問題解決。  

ASP.NET 使用mode=”InProc”方式儲存Session老是丟失,無奈改成StateServer 模式。

session是工作在你的應用程式程序中的。asp.net程序、iis往往會在20分鐘之後重啟相關的應用程式,緩衝池滿了(例如100個之後)也會重啟,各種程序保護措施都會隨時重新啟動,因此InProc方式丟失session是很正常的事。csdn上明確告訴了這種模式只能儲存易失的、暫時的變數,這是cache沒有之前的一種解決方案。而長期保持的資料就要儲存在外部資料來源中。狀態伺服器就是一種程序外的資料來源。 

StateServer 模式的實質是,把Session 存放在一個單獨的程序裡,此程序獨立於 aspnet_wp.exe w3wp.exe 。啟用此服務後,在工作管理員中可以看到一個名為 aspnet_state.exe 的程序,下面開始說明一下設定的具體步驟:

1、 修改登錄檔(關鍵步驟,如下圖)

執行 regedit 開啟登錄檔 → 找到HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state /Parameters 節點 → AllowRemoteConnection 的鍵值設定成“1”1 為允許遠端電腦的連線,0 代表禁止)→ 設定 Port (埠號,在web.config中要設定的port要跟這裡設定的一致)

注意事項:

a)、若ASP.NET State Service 正在執行,修改登錄檔內容後,則需要重新啟動該服務

b)、注意埠號的鍵值是以十六進位制儲存的,可以使用十進位制進行修改,42424 是預設的埠

c)AllowRemoteConnection 的鍵值設定成“1”後,意味著允許遠端電腦的連線,也就是說只要知道你的服務埠,就可享用你的ASP.NET State Service,即把 Session 存放在你的電腦程序內,因此請大家慎用;鍵值為“0”時,僅有stateConnectionString “tcpip=localhost: 42424”“tcpip=127.0.0.1:42424”的情況,方可使用ASP.NET State Service

2、 開啟 ASP.NET State Service

右鍵點選我的電腦 管理 → 服務與應用程式 → 服務 → 雙擊“ASP.NET State Service” 啟動(可設為自動

說明:只要安裝了 .Net Framework ,都擁有此服務。

3、 更改 Web.config

開啟 Web.config 找到 <sessionState> 節點內容

<sessionState

mode=”InProc”

stateConnectionString=”tcpip=127.0.0.1:42424″

sqlConnectionString=”data source=127.0.0.1;Trusted_Connection=yes”

cookieless=”false”

timeout=”20″ />

將其改為以下內容(注意:當發生“無法向會話狀態伺服器發出會話狀態請求。"異常時,將mode="InProc",其他不變

<sessionState mode=”StateServer” stateConnectionString=”tcpip=192.168.0.2:42424″ timeout=”20″ /> 

注意事項:
1
timeout=”20″Session 20分鐘超時

2IP 地址(可以是遠端計算機 IP、計算機名稱、域名)與埠號,埠號需與ASP.NET State Service 的服務埠一致