跨 Web 應用程序共享 SQL Server 會話狀態
我正在設置一個非常基本的 SQL Server 會話狀態展示,但是在讓它工作時遇到了一些麻煩。我正在嘗試使用 IIS 7.5 和 SQL Server 2008 R2 在本地執行 Windows 7 進行測試。
最終,我需要一種方法來跟踪登錄到在幾個不同 Web 伺服器之間進行負載平衡的系統的使用者數量。因此,每次使用者登錄或註銷時,我都需要更新一個會話變數(儲存在 SQL 中)。所以會話 ID 可能總是不同的。這可能嗎?
這是我到目前為止所做的:
- 在 IIS 中創建了兩個新站點(Site1 和 Site2)
- 在 VS 2010 中創建了兩個新的 Web 應用程序項目(Site1 和 Site2)
- 在這兩個站點中,在 Default.aspx 頁面上,我創建了一個按鈕,點擊該按鈕時會將“Site1”或“Site2”(取決於站點)保存到名為“LastSiteUsed”的會話變數中。還有另一個按鈕,點擊該按鈕時,將從“LastSiteUsed”會話變數中讀取值並將其顯示在標籤中。
- 在 SQL 中,我創建了一個名為 dbSessionTest 的新數據庫。然後我按照MSDN 上的說明使用 aspnet_regsql 工具安裝會話狀態數據庫。
- 在我的兩個 Web 應用程序的 Web.config 文件中,我在下面添加了以下內容
<System.Web>:
<sessionState mode="SQLServer" sqlConnectionString="server=.\sqlexpress;database=dbSessionTest;uid=myUsername;pwd=myPassword" cookieless="false" timeout="20" allowCustomSqlDatabase="true"/>兩個站點都正常執行,但它們似乎沒有共享會話。例如,當我點擊按鈕從 Site1 保存會話變數時,我希望能夠從 Site2 讀取該值,但它不起作用。Site2 只會返回“Site2”,Site1 只會返回“Site1”。
有人對我可能做錯的事情有任何想法嗎?我認為我應該能夠從 Site2 讀取 Site1 設置的值是錯誤的嗎?
更新:
我可以看到會話數據儲存在
ASPStateTempSessionsSQL Management Studio 的表中,但每個站點仍然只能看到它寫入的值。兩個站點都像這樣設置會話變數:Session("LastSiteUsed") = "Site2"兩個站點都在檢索以下值:
lblValue.Text = "Value from Session: " & Session("LastSiteUsed").ToString訪問儲存在 SQL Server 中的會話變數是否需要以不同的方式執行此操作?
更新 2:
我嘗試使用預設數據庫 ASPState,它是通過執行以下命令創建的:
aspnet_regsql.exe -S MyServerName -E -ssadd -sstype p然後簡化了我的每個 Web.config 文件,例如:
<sessionState mode="SQLServer" sqlConnectionString="Data Source=.\sqlexpress;User ID=myUsername;Password=myPassword" cookieless="false" timeout="20"/>但同樣,沒有運氣。我希望能夠從 Site1 設置會話變數,然後從 Site2 讀取值,但它不起作用。同樣,我可以看到表格中出現的條目,
ASPStateTempSessions所以我知道它們輸入正確。我注意到的一件事是他們有不同的會話 ID?在設置/讀取相同的會話變數時,我是否需要做一些不同的事情來確保在我的站點之間使用相同的會話 ID?
更新 3:
我已按照**本文**中的說明修改了 SP 並向表中添加了用於分組的
ASPStateTempApplications列。這種工作,但前提是我的兩個網站都在同一個瀏覽器中打開(使用標籤)*。*我需要能夠在 IE 中打開 Site1,將值保存到我的會話變數,關閉瀏覽器,在 Chrome 中打開 Site2,然後讀取值。從我用 SQL Server 會話狀態讀到的所有內容……這應該是可能的。更新 4 - 解決方案:
我遵循了@SilverNinja 提供的**這篇文章的答案。**我通過命令提示符重新創建了
ASPState數據庫(以撤消更新 #3 中的 SP 更改),然後TempGetAppID根據連結中的答案修改了 SP。我還更新了我的兩個 Web.config 文件以匹配該文章中的答案:<sessionState mode="SQLServer" sqlConnectionString="Data Source=.\sqlexpress;User ID=myUsername;Password=myPassword;Application Name=CacheTest"/>我還在兩個 Web.config 文件中包含了相同的機器密鑰:
<machineKey validationKey="59C42C5AB0988049AB0555E3F2128061AE9B75E3A522F25B34A21A46B51F188A5C0C1C74F918DFB44C33406B6E874A54167DFA06AC3BE1C3FEE8506E710015DB" decryptionKey="3C98C7E33D6BC8A8C4B7D966F42F2818D33AAB84A81C594AF8F4A533ADB23B97" validation="SHA1" decryption="AES" />現在我可以(使用 IE)打開我的兩個站點,從 Site1 設置一個值,然後從 Site2 讀取它(反之亦然)。當我檢查表格時,只有一個 SessionID 存在(兩個站點都正確使用相同的會話)。在打開新瀏覽器(例如,使用 Chrome)之前,我的想法是錯誤的,會使用相同的會話 - 新瀏覽器將啟動它自己的會話。但是,在負載平衡的情況下,這不會導致任何問題。
您遇到的問題是跨 ASP.NET 應用程序共享會話狀態。SQL Server 會話提供程序不支持開箱即用。請參閱此SO 文章,了解對 SQL Server 會話提供程序進行哪些更改以支持跨應用程序會話。
我不會使用 session 來管理這個共享狀態(即
LastSiteUsed)。此資訊應與使用者配置文件儲存(成員資格、配置文件提供者、自定義數據庫等)一起保存。由於會話可能過期 - 跨應用程序使用共享會話不是跟踪持久使用者特定狀態的可靠機制。如果持久性不重要,則將AppFabric 記憶體用於記憶體中的跨應用程序共享狀態。