日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

理解Session的幾種模式

 Levy_X 2017-09-09
一、寫在前面 

  我們在使用ASP.NET開發(fā)的過程中,有時(shí)會進(jìn)行數(shù)據(jù)存儲以實(shí)現(xiàn)請求前后的狀態(tài)保持(HTTP是無狀態(tài)保持的協(xié)議),而Session作為一種快速簡單易于實(shí)現(xiàn)的方式被我們經(jīng)常使用,當(dāng)然如果出于性能方面的考量,我們還是不建議往Seesion中塞入更多的東西,最好是不用Session。

  還有一點(diǎn)需要說明的是,Session實(shí)現(xiàn)的本質(zhì)是在客戶端產(chǎn)生一個(gè)SessionId,具體的數(shù)據(jù)存儲在服務(wù)器端,客戶端通過SessionId來獲取服務(wù)器端的具體數(shù)據(jù),那這個(gè)SeesionId是怎么保存在客戶端以及又是以什么方式來傳給服務(wù)器的呢?服務(wù)器端又是以什么方式保存Session的這些數(shù)據(jù)的呢?各種方式的優(yōu)缺點(diǎn)又是什么?這就是本篇隨筆想要記錄的內(nèi)容。

二、配置方式 
  <sessionState mode='Off|InProc|StateServer|SQLServer' 
  cookieless='true|false' 
  timeout='number of minutes' 
  stateConnectionString='tcpip=server:port' 
  sqlConnectionString='sql connection string' 
  stateNetworkTimeout='number of seconds' />

上面是Session在Web.config的配置方式,下面對各個(gè)節(jié)點(diǎn)做一些簡單的介紹 

mode(設(shè)置將服務(wù)器的Session信息存儲到哪里) 

Off表示設(shè)置為不使用Session功能;
InProc表示將Session存儲在進(jìn)程內(nèi),這也是ASP中的存儲方式,這是默認(rèn)值;
StateServer表示將Session存儲在獨(dú)立的狀態(tài)服務(wù)即ASP.NET State Service中;
SQLServer表示將Session存儲在SQL Server。

cookieless(設(shè)置客戶端的Session信息存儲到哪里) 

true表示使用Cookieless模式(這表明SessionId將不再使用Cookie存儲了,而是將其通過URL存儲);
false表示使用Cookie模式,這是默認(rèn)值。

從上面的設(shè)置配置中我們也可以發(fā)現(xiàn)Session和Cookie的關(guān)系: 

首先Session在客戶端的實(shí)現(xiàn)肯定是SessionId;
默認(rèn)這個(gè)SessionId是通過Cookie存儲的(比較安全);
當(dāng)然也可以通過URL來進(jìn)行存儲,這樣Session和Cookie就沒有關(guān)系了,但是此種方式由于受URL長度限制以及明文傳送導(dǎo)致不安全而不被推薦使用。
timeout 

Session過期時(shí)間設(shè)置,默認(rèn)為20分鐘。 

stateConnectionString

如果設(shè)置將Session信息存儲在State Server中時(shí),則需要此配置字符串表明服務(wù)器名稱和端口。 

sqlConnectionString   

如果設(shè)置將Session信息存儲在SQL Server中,需此配置,表明數(shù)據(jù)庫的連接字符串,同時(shí)stateNetworkTimeout表明經(jīng)過多少秒空閑后,斷開Web服務(wù)器與存儲狀態(tài)信息的服務(wù)器的TCP/IP連接的。默認(rèn)值是10秒鐘。  

三、Session服務(wù)器端配置 

1. InProc 

  顧名思義,此種模式表示Session將會被保存在內(nèi)存中,確切地說是保存在工作者進(jìn)程中,對于IIS 5而言是aspnet_wp.exe,對于IIS 6而言是w3wp.exe,設(shè)置方式如下(Web.config)

<sessionState mode='InProc' cookieless='false' timeout='20'/> 

  由于是直接保存在進(jìn)程中,所以性能最好,但是經(jīng)常會發(fā)生Session信息丟失,常見的導(dǎo)致進(jìn)程重啟的可能情況為:

配置文件中processModel標(biāo)簽的memoryLimit屬性;
Global.asax或者Web.config文件被更改;
Bin文件夾中的Web程序(DLL)被修改;
殺毒軟件掃描了一些.config文件;
系統(tǒng)資源緊張進(jìn)行資源回收導(dǎo)致IIS進(jìn)程崩潰或重啟等。

2. State Server 

  此種方式是將Session信息存儲在其它的進(jìn)程中而不是IIS中,這樣就可以避免因IIS進(jìn)程崩潰或重啟而導(dǎo)致的Session信息丟失。但是此種方式要求保存在Session的信息必須序列化,然后從Session中獲取的時(shí)候也要反序列化,這就導(dǎo)致性能有略微的損失。

<sessionState mode='StateServer' cookieless='false' timeout='20'/> 

  StateServer是本機(jī)的一個(gè)服務(wù),可以在系統(tǒng)服務(wù)里看到服務(wù)名為ASP.NET State Service的服務(wù),默認(rèn)情況是不啟動(dòng)的。當(dāng)我們設(shè)定mode為StateServer之后,請把該服務(wù)的啟動(dòng)模式設(shè)置為自動(dòng)(這樣下次服務(wù)就可以隨機(jī)器而啟動(dòng))并手工將該服務(wù)啟動(dòng)運(yùn)行。這樣,我們就能利用本機(jī)的StateService來存儲Session了,除非電腦重啟或者StateService崩掉,否則Session是不會丟的。

<sessionState mode='StateServer' stateConnectionString='tcpip=127.0.0.1:42424' cookieless='false' timeout='20'/> 

  此種配置和上面是一樣的(多了個(gè)stateConnectionString,換句話說127.0.0.1是默認(rèn)本機(jī)IP,42424默認(rèn)是該服務(wù)的訪問端口號,寫不寫效果是一樣的),都表示StateServer是在本機(jī)(注:StateServer模式是支持遠(yuǎn)程主機(jī)服務(wù)的,配置類似與下面)

<sessionState mode='StateServer' stateConnectionString='tcpip=10.7.10.87:42424' cookieless='false' timeout='20'/> 

  注:如果在啟動(dòng)ASP.NET State Service服務(wù)時(shí)遇到問題0x8007277a 即無法啟動(dòng)或初始化,請嘗試在命令行(CMD)中輸入netsh winsock reset(有可能是winsock的問題,所以需reset一下)

3. SQL Server 

  此種方式是把Session信息保存在SQL Server的數(shù)據(jù)庫中,也需要序列化,性能有較大損失,但是Session一般不會發(fā)生丟失的情況,除非SQL Server宕機(jī)。而且此種方式也可以實(shí)現(xiàn)在Web Farm中的Session信息共享(上面兩種方式都不可以)。

<sessionState mode='SQLServer' sqlConnectionString ='data source=10.7.11.114; user id=session_user; password=Session@Pwd' timeout='20' /> 

3.1 安裝ASPState數(shù)據(jù)庫 

在使用之前,我們要安裝配置對應(yīng)的數(shù)據(jù)庫,而微軟給我們提供了一整套方案(你也可以選擇使用自己的數(shù)據(jù)庫或自己實(shí)現(xiàn)配置和管理)。ASP.NET 2.0版本后微軟提供了aspnet_regsql.exe工具可以方便的配置Session數(shù)據(jù)庫,該工具位于 Web 服務(wù)器上的'系統(tǒng)根目錄\Microsoft.NET\Framework\版本號'文件夾中. 

使用舉例: 

aspnet_regsql.exe -S . -U session_user -P Session@Pwd -ssadd -sstype p 

-S參數(shù): 

表示數(shù)據(jù)庫實(shí)例名稱. 可以用'.'表示本機(jī),你也可以指定機(jī)器,如10.7.11.110等 

-U和-P參數(shù): 

表示用戶名和密碼. 

-E參數(shù): 

可以再-U –P 與 -E中選擇一組. –E表示以當(dāng)前系統(tǒng)用戶通過windows身份驗(yàn)證登錄數(shù)據(jù)庫, -U -P則是使用SqlServer用戶登錄數(shù)據(jù)庫. 

-ssadd / –ssremove 參數(shù): 

-ssadd表示是添加Session數(shù)據(jù)庫, -ssremove表示移除Session數(shù)據(jù)庫. 

sstype 參數(shù): 
選項(xiàng) 說明 

將會話數(shù)據(jù)存儲到 SQL Server tempdb 數(shù)據(jù)庫中。這是默認(rèn)設(shè)置。如果將會話數(shù)據(jù)存儲到 tempdb 數(shù)據(jù)庫中,則在重新啟動(dòng) SQL Server 時(shí)將丟失會話數(shù)據(jù)。 

將會話數(shù)據(jù)存儲到 ASPState 數(shù)據(jù)庫中,而不是存儲到 tempdb 數(shù)據(jù)庫中。 

將會話數(shù)據(jù)存儲到自定義數(shù)據(jù)庫中。如果指定 c 選項(xiàng),則還必須使用 -d 選項(xiàng)包括自定義數(shù)據(jù)庫的名稱。 

注意:如果sstype為t,則在下面的用戶權(quán)限賦予中要授予對tempdb的dbowner權(quán)限,否則將無法操作數(shù)據(jù)庫。  

3.2 建立連接數(shù)據(jù)庫 ASPState 的用戶,并為此用戶授權(quán) 

  運(yùn)行 SQL Server 的企業(yè)管理器   展開數(shù)據(jù)庫的安全性   右擊'登錄'   新建'登錄'   輸入'名稱'   選擇 'SQL Server 身份驗(yàn)證'   輸入'密碼'   指定'數(shù)據(jù)庫'   點(diǎn)擊'數(shù)據(jù)庫訪問'   勾選 'ASPState'   選中'db_owner'角色   點(diǎn)擊'確定'   再一次輸入'密碼'   點(diǎn)擊'確定' 后即可建立 ASPState 的用戶,下面用命令實(shí)現(xiàn):

--新建數(shù)據(jù)庫賬號 SessionStateUser ,默認(rèn)登錄 ASPState 
EXEC sp_addlogin 'SessionStateUser', '123456', 'ASPState' 

use ASPState         --切換 DataBase 
--將 SessionStateUser 授予 db_owner 的權(quán)限 
exec sp_adduser 'SessionStateUser', 'SessionUser' ,'db_owner' 

3.3 啟動(dòng)SQL Server Agent 

  自動(dòng)運(yùn)行Job ASPState_Job_DeleteExpiredSessions刪除過期的Session,否則數(shù)據(jù)庫中的數(shù)據(jù)將一直增長。

四、Session客戶端配置 

  再次說明,Session的實(shí)現(xiàn)分為兩個(gè)部分:客戶端和服務(wù)器端,其中客戶端負(fù)責(zé)產(chǎn)生SessionId,服務(wù)器端負(fù)責(zé)保存具體的內(nèi)容,這兒所說的Session客戶端配置其實(shí)是想說說關(guān)于SessionId的一些東西。

1. Session在客戶端是如何實(shí)現(xiàn)的? 

  前面已經(jīng)說過,Session在客戶端是通過產(chǎn)生SessionId來實(shí)現(xiàn)的,至于這個(gè)SessionId又是通過什么方式回傳之服務(wù)器從而獲得具體的Session內(nèi)容,前面也略有說明,兩種方式:Cookie和Url,由于Url的方式會導(dǎo)致安全性問題,所以現(xiàn)在一般已不再使用此種方式。

  當(dāng)系統(tǒng)是用Session的時(shí)候,系統(tǒng)將自動(dòng)在客戶端產(chǎn)生一個(gè)Cookie,名稱為ASP.NET_SessionId,為了便于區(qū)別,我們暫且將此Cookie稱為Session Cookie

2. Session Cookie何時(shí)失效? 

  和一般的Cookie一樣,默認(rèn)是保存在瀏覽器的內(nèi)存中,當(dāng)瀏覽器關(guān)閉時(shí)失效,如果想此Cookie保存在本地磁盤,可通過設(shè)置其Expires屬性來達(dá)到,這種方式現(xiàn)在也被廣泛應(yīng)用于網(wǎng)站的登錄,即用戶在登錄的時(shí)候選擇記住我或保持登錄一段時(shí)間,這樣當(dāng)用戶下次再次訪問的時(shí)候就無需再次輸入用戶名密碼從而達(dá)到快速訪問的目的

HttpCookie httpCookie = new HttpCookie('ASP.NET_SessionId', Request.Cookies['ASP.NET_SessionId'].Value); 
httpCookie.Expires = DateTime.Now.AddMinutes(20); 
Response.Cookies.Add(httpCookie); 
if (!string.IsNullOrEmpty(Request.Cookies['ASP.NET_SessionId'].Value)) 

  //...處理相關(guān)登錄驗(yàn)證等信息 
  Response.Redirect('Default.aspx?UserName='   loginUser.UserName   ''); 

3. Session Cookie失效時(shí)Session失效嗎? 

  答案當(dāng)然是否定的,記?。篠ession Cookie和Session的失效沒有任何必然的聯(lián)系,因?yàn)樗鼈兪У幕鶞?zhǔn)或者條件根本不一樣,Session Cookie的失效時(shí)間取決于客服端Cookie的失效時(shí)間,如果是保存在瀏覽器中,那么關(guān)閉瀏覽器Session Cookie就將失效,否則如果保存在本地磁盤,則取決于該Session Cookie設(shè)置的過期時(shí)間;而服務(wù)器端的Session是保存在服務(wù)器端的,它的失效與否與其服務(wù)器端的設(shè)置和Session的過期時(shí)間有關(guān)(下面的討論將忽略過期時(shí)間這個(gè)因數(shù),你懂的),如果是InProc方式,那么當(dāng)承載的IIS進(jìn)程如果奔潰或重啟等都會丟失;如果是State Server,同樣如果這個(gè)Service宕掉,那Session也會丟失;而如果是SQL Server,則會寫入數(shù)據(jù)庫,如果你不刪除它,它甚至可以一直存在而永不丟失(事實(shí)是SQL Server Agent會自動(dòng)運(yùn)行一個(gè)Job刪除過期的Session);而當(dāng)如果我們使用自定義的數(shù)據(jù)庫來保存Session時(shí),你將獲得充分的控制。

4. Session Cookie何時(shí)產(chǎn)生?刷新頁面其值會改變嗎? 

  牢記一點(diǎn),只有當(dāng)使用Session的時(shí)候才會產(chǎn)生Session Cookie。你也許會反問那為什么當(dāng)配置Session模式為SQLServer時(shí),就算沒有使用Session,也可以獲得ASP.NET_SessionId的值,即在Page_Load的時(shí)候執(zhí)行方法Response.Write(Request.Cookies['ASP.NET_SessionId'].Value),會輸出值,我的猜測是雖然你可以獲得ASP.NET_SessionId值,但實(shí)際上并沒有真正產(chǎn)生Session Cookie,因?yàn)榇藭r(shí)當(dāng)我試圖通過HttpWatch(下面介紹的工具)來查看此Session Cookie的時(shí)候根本查不到,當(dāng)然這也只是我的個(gè)人猜測而已,至于具體的內(nèi)部機(jī)制還是不甚了解。

  當(dāng)沒有使用Session的時(shí)候刷新頁面Session Cookie的值會變化嗎?答案是會的,測試方法如上,設(shè)置Session模式為SQLServer,在Page_Load的時(shí)候輸出Session Cookie的值,然后一直F5頁面即可,你會看到其值一直在變化,直到在代碼中明確地使用Session后便不再變化。

復(fù)制代碼
public partial class Login : System.Web.UI.Page 

  protected void Page_Load(object sender, EventArgs e) 
    { 
  Response.Write(Request.Cookies['ASP.NET_SessionId'].Value); 
    } 

  protected void tbnLogin_Click(object sender, EventArgs e) 
    { 
  if (!string.IsNullOrEmpty(this.txtUserName.ToString()) && !string.IsNullOrEmpty(this.txtPassword.ToString())) 
        { 
  LoginUser loginUser = new LoginUser(); 
  loginUser.UserId = Guid.NewGuid().ToString('N'); 
  loginUser.UserName = this.txtUserName.Text; 
  loginUser.UserPassword = this.txtPassword.Text; 
  Session['LoginUser'] = loginUser; 
        }      }  } 
復(fù)制代碼

5. Session Cookie如何查看 

  如果設(shè)置了Session Cookie的過期時(shí)間,則此Session Cookie會保存在本地磁盤,一般是在目錄C:\Documents and Settings\user\Local Settings\Temporary Internet Files,此目錄可手工設(shè)置(Internet選項(xiàng)->常規(guī)->瀏覽歷史記錄中的'設(shè)置'選項(xiàng)->Internet臨時(shí)文件的'查看文件'選項(xiàng))。

  如果沒有設(shè)置過期時(shí)間,則Session Cookie默認(rèn)是保存在瀏覽器內(nèi)存中的,Chrome瀏覽器默認(rèn)支持查看Cookie,具體步驟如下:Tools - > Settings ->Show Advanced Settings -> Privacy -> Content Settings -> Cookies -> All cookies and site data,不過坑爹的是它只支持查看和刪除,不支持修改,如果你想修改的話,我們只能通過第三方插件來完成https://chrome.google.com/webstore/detail/fngmhnnpilhplaeedifhccceomclgfbg(Chrome Web Store瀏覽下載安裝即可) 

SosoImg

  如果你使用的是IE瀏覽器,你也要通過安裝插件HttpWatch來查看(Firefox也適用)

SosoImg

五、Session的其它相關(guān)問題 

1. 如何捕獲Global.asax中的Session_End()事件? 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多