我正在设置一个非常基本的 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 设置的值是错误的吗?
更新:
我可以看到会话数据存储在ASPStateTempSessions
SQL 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)之前,我的想法是错误的,会使用相同的会话 - 新浏览器将启动它自己的会话。但是,在负载平衡的情况下,这不会导致任何问题。