一、安装session数据库
使用VS自带的命令工具 到 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 目录下面使用命令
例如:aspnet_regsql.exe -ssadd -sstype c -d [DB] -S [Server] –E (使用相应命令可以对远程数据库进行创建)
具体参数说明参考:http://msdn.microsoft.com/zh-cn/library/ms229862(VS.80).aspx
其实使用的是文件夹下面的:InstallSqlState.sql 与InstallPersistSqlState.sql 前一个是在temp数据库中,重启数据库将会session丢失,后一个在独立数据库中,重启数据库session不会丢失
但是在数据库中直接使用这两个文件进行创建将会出现错误,不知道代理服务开始时候还会出现,但是使用命令就算代理服务没有开启也是可以创建的
二、配置web.config
<sessionState mode="SQLServer" sqlConnectionString="data source=[Server];initial catalog=[DB];user id=[User Name];password=[Password]" cookieless="false" timeout="60"></sessionState>
三、修改数据库存储过程
通过以上配置session已经保存在数据库中,但是不同的站点其SessionID是不同的,就算SessionID相同了,保存在会话数据库中的实际SessionID的值也不只是网站生成的SessionID,而是在SessionID后加上了站点的AppName,因此即使各个站点共享了会话数据库也不能共享会话数据。
CREATE
PROCEDURE
dbo.TempGetAppID
@appName
tAppName,
@appId
int
OUTPUT
AS
SET
@appName
=
LOWER
(
@appName
)
SET
@appId
=
NULL
SELECT
@appId
=
AppId
FROM
[
JSEC_SessionDB
]
.dbo.ASPStateTempApplications
WHERE
AppName
=
@appName
IF
@appId
IS
NULL
BEGIN
BEGIN
TRAN
SELECT
@appId
=
AppId
FROM
[
JSEC_SessionDB
]
.dbo.ASPStateTempApplications
WITH
(TABLOCKX)
WHERE
AppName
=
@appName
IF
@appId
IS
NULL
BEGIN
EXEC
GetHashCode
@appName
,
@appId
OUTPUT
INSERT
[
JSEC_SessionDB
]
.dbo.ASPStateTempApplications
VALUES
(
@appId
,
@appName
)
IF
@@ERROR
=
2627
BEGIN
DECLARE
@dupApp
tAppName
SELECT
@dupApp
=
RTRIM
(AppName)
FROM
[
JSEC_SessionDB
]
.dbo.ASPStateTempApplications
WHERE
AppId
=
@appId
RAISERROR
(
'
SQL session state fatal error: hash-code collision between applications
''
%s
''
and
''
%s
''
. Please rename the 1st application to resolve the problem.
'
,
18
,
1
,
@appName
,
@dupApp
)
END
END
COMMIT
END
RETURN
0
GO
修改以上第五行 set @appName='XXX' 任意值使每个站点使用相同的appName
四、修改Cookie保存方式确保cookie使用相同主域
public
class
CrossDomainCookie : IHttpModule
{
private
string
m_RootDomain
=
string
.Empty;
#region
IHttpModule Members
public
void
Dispose()
{
}
public
void
Init(HttpApplication context)
{
m_RootDomain
=
ConfigurationManager.AppSettings[
"
RootDomain
"
];
Type stateServerSessionProvider
=
typeof
(HttpSessionState).Assembly.GetType(
"
System.Web.SessionState.OutOfProcSessionStateStore
"
);
FieldInfo uriField
=
stateServerSessionProvider.GetField(
"
s_uribase
"
, BindingFlags.Static
|
BindingFlags.NonPublic);
if
(uriField
==
null
)
throw
new
ArgumentException(
"
UriField was not found
"
);
uriField.SetValue(
null
, m_RootDomain);
context.EndRequest
+=
new
System.EventHandler(context_EndRequest);
}
void
context_EndRequest(
object
sender, System.EventArgs e)
{
HttpApplication app
=
sender
as
HttpApplication;
for
(
int
i
=
0
; i
<
app.Context.Response.Cookies.Count; i
++
)
{
app.Context.Response.Cookies[i].Domain
=
m_RootDomain;
}
}
#endregion
}
以上参考:
http://www.cnblogs.com/jzywh/archive/2008/11/02/sharesession.html
五、修改web.config
<
appSettings
>
<
add
key
="RootDomain"
value
=".test.com"
/>
</
appSettings
>
<
system.web
>
<
machineKey
decryptionKey
="FD69B2EB9A11E3063518F1932E314E4AA1577BF0B824F369"
validationKey
="5F32295C31223A362286DD5777916FCD0FD2A8EF882783FD3E29AB1FCDFE931F8FA45A8E468B7A40269E50A748778CBB8DB2262D44A86BBCEA96DCA46CBC05C3"
validation
="SHA1"
decryption
="Auto"
/>
<
sessionState
mode
="SQLServer"
sqlConnectionString
="data source=[Server];initial catalog=[DB];user id=[User Name];password=[Password]"
cookieless
="false"
timeout
="60"
></
sessionState
>
<
httpModules
>
<
add
name
="CrossDomainCookieModule"
type
="Test.HttpModule.CrossDomainCookie, GB87.HttpModule"
/>
</
httpModules
>
</
system.web
>
<
system.webServer
>
<
modules
>
<
add
name
="CrossDomainCookieModule"
preCondition
="managedHandler"
type
="Test.HttpModule.CrossDomainCookie, GB87.HttpModule"
/>
</
modules
>
</
system.webServer
>
以上完成了 所有的配置
接下来就是配置在IIS上面 创建两个网站 http://www.test.com/ http://a.test.com/
并修改host文件 指向127.0.0.1 进行测试 通过测试
配置使用过程中发现的问题:
在使用session保存对象的时候一定要能够序列化,类名前面加[Serializable],而且在我测试的时候两个网站没有使用相同的实体层,实体层的名字不同造成无法转化的问题
其他参考:
http://hi.baidu.com/hiqb/blog/item/1b935fee2878b3f7b2fb9542.html
http://www.cnblogs.com/leonsky/articles/1427014.html