实现多个asp.net应用程序间的Session共享。
查阅资料N多,多不可行,可能可行的(包括微软官方方法)都需要改动应用程序本身很多...麻烦!很不悦!
最终,找到一个解决方案...不过估计微软会不悦。
大致思路:
采用SqlServer方式存储Session,分析数据库表结构、原理、流程,大致可以得到SqlServer存储Session的方法:
表结构:
ASPStateTempApplications表存储应用程序Id及名称
ASPStateTempSessions表存储具体的Session值
不同的应用程序会在ASPStateTempApplications中注册不同的数据,从而在ASPStateTempSessions中有不同的Session,如果要实现Session共享,可以用欺骗SqlServer的方法: 用某种方法使得不同的应用程序访问数据库时用相同的App!为了达到这个目的,分析[dbo].[TempGetAppID]这个存储过程,代码如下:
好了(不知道这样做微软会不会很不悦...),大功告成,清理残留的Session,最好重启一下IIS,不用修改旧程序本身丝毫(配置web.config除外),实现了Session共享...以后凡是使用该数据库作为Session存储的都可以共享Session了...
其他的一些配置说明如下:
配置web.config节:
配置SQLServer:
修改[dbo].[TempGetAppID]:将@appName设为一个定值,修改保存。
清理Session,重启IIS,KO!
查阅资料N多,多不可行,可能可行的(包括微软官方方法)都需要改动应用程序本身很多...麻烦!很不悦!
最终,找到一个解决方案...不过估计微软会不悦。
大致思路:
采用SqlServer方式存储Session,分析数据库表结构、原理、流程,大致可以得到SqlServer存储Session的方法:
表结构:
ASPStateTempApplications表存储应用程序Id及名称
ASPStateTempSessions表存储具体的Session值
不同的应用程序会在ASPStateTempApplications中注册不同的数据,从而在ASPStateTempSessions中有不同的Session,如果要实现Session共享,可以用欺骗SqlServer的方法: 用某种方法使得不同的应用程序访问数据库时用相同的App!为了达到这个目的,分析[dbo].[TempGetAppID]这个存储过程,代码如下:
Code
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 1 ALTER PROCEDURE [dbo].[TempGetAppID]
2 @appName tAppName,
3 @appId int OUTPUT
4 AS
5 SET @appName = LOWER(@appName)
6 SET @appId = NULL
7
8 SELECT @appId = AppId
9 FROM [Herald.Session].dbo.ASPStateTempApplications
10 WHERE AppName = @appName
11
12 IF @appId IS NULL BEGIN
13 BEGIN TRAN
14
15 SELECT @appId = AppId
16 FROM [Herald.Session].dbo.ASPStateTempApplications WITH (TABLOCKX)
17 WHERE AppName = @appName
18
19 IF @appId IS NULL
20 BEGIN
21 EXEC GetHashCode @appName, @appId OUTPUT
22
23 INSERT [Herald.Session].dbo.ASPStateTempApplications
24 VALUES
25 (@appId, @appName)
26
27 IF @@ERROR = 2627
28 BEGIN
29 DECLARE @dupApp tAppName
30
31 SELECT @dupApp = RTRIM(AppName)
32 FROM [Herald.Session].dbo.ASPStateTempApplications
33 WHERE AppId = @appId
34
35 RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.',
36 18, 1, @appName, @dupApp)
37 END
38 END
39
40 COMMIT
41 END
42
43 RETURN 0
可以看到传入参数是AppName,通过AppName获取AppId,如果不存在则在ASPStateTempApplications表中插入该条记录,这里AppName参数在传入时是不同的应用程序不同的,当然我们可以在这里小改一下...注意第5行
SET
@appName
=
LOWER
(
@appName
) 我们可以毫不客气的改成
SET
@appName
=
'Everything you want ^_^'
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> 1 ALTER PROCEDURE [dbo].[TempGetAppID]
2 @appName tAppName,
3 @appId int OUTPUT
4 AS
5 SET @appName = LOWER(@appName)
6 SET @appId = NULL
7
8 SELECT @appId = AppId
9 FROM [Herald.Session].dbo.ASPStateTempApplications
10 WHERE AppName = @appName
11
12 IF @appId IS NULL BEGIN
13 BEGIN TRAN
14
15 SELECT @appId = AppId
16 FROM [Herald.Session].dbo.ASPStateTempApplications WITH (TABLOCKX)
17 WHERE AppName = @appName
18
19 IF @appId IS NULL
20 BEGIN
21 EXEC GetHashCode @appName, @appId OUTPUT
22
23 INSERT [Herald.Session].dbo.ASPStateTempApplications
24 VALUES
25 (@appId, @appName)
26
27 IF @@ERROR = 2627
28 BEGIN
29 DECLARE @dupApp tAppName
30
31 SELECT @dupApp = RTRIM(AppName)
32 FROM [Herald.Session].dbo.ASPStateTempApplications
33 WHERE AppId = @appId
34
35 RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.',
36 18, 1, @appName, @dupApp)
37 END
38 END
39
40 COMMIT
41 END
42
43 RETURN 0
好了(不知道这样做微软会不会很不悦...),大功告成,清理残留的Session,最好重启一下IIS,不用修改旧程序本身丝毫(配置web.config除外),实现了Session共享...以后凡是使用该数据库作为Session存储的都可以共享Session了...
其他的一些配置说明如下:
配置web.config节:
<
sessionState
mode
="SQLServer"
sqlConnectionString
="data source=[Server];initial catalog=[DataBase];user id=[UserName];password=[Password]"
allowCustomSqlDatabase
="true"
timeout
="120"
/>
配置SQLServer:
aspnet_regsql.exe
-
sstype c
-
ssadd
-
d [DataBase]
-
U [UserName]
-
P [Password]
-
S [Server]
修改[dbo].[TempGetAppID]:将@appName设为一个定值,修改保存。
清理Session,重启IIS,KO!