最近在做一个项目,这个项目是采用的Web服务,客户端是WinCE 4.1+.Net Framework CF版。大家知道,要保存当前会话状态(当前登录的用户信息,当前操作的单据等)最好是用Session来保存,Web service中也提供了session的支持。在一般的应用中使用Session是没有问题的,只需要把声明一个CookieContainer对象就可以了。如下:


经过几天的思考后,终于想到了一个解决办法:在服务器端用一个静态的HashTable模拟Session对象,用客户端的IP地址作为关键字,代码如下:
1
public class Global : System.Web.HttpApplication
2

{
3
private System.ComponentModel.IContainer components = null;
4
private static Hashtable UserSession;
5
private static int Session_timeout; //Session超时时间
6
7
8
public Global()
9
{
10
InitializeComponent();
11
}
12
13
protected void Application_Start(Object sender, EventArgs e)
14
{
15
UserSession=new Hashtable();
16
Session_timeout=60;
17
}
18
19
protected void Session_Start(Object sender, EventArgs e)
20
{
21
Session["ip"]=Request.UserHostAddress;
22
23
//检测到该Ip是第一次访问或者Session已经超时,则把当前Session加入到HashTable中
24
if(UserSession[Request.UserHostAddress]==null || DateTime.Compare(DateTime.Now,((DateTime)UserSession[Request.UserHostAddress+"_time"]).AddMinutes(Session.Timeout))>0)
25
{
26
UserSession[Request.UserHostAddress]=Session;
27
}
28
//保存最近一次访问时间
29
UserSession[Request.UserHostAddress+"_time"]=DateTime.Now;
30
}
31
32
//外部的函数可以通过这个函数读取Session
33
public static System.Web.SessionState.HttpSessionState mySession(string IP)
34
{
35
return (System.Web.SessionState.HttpSessionState)UserSession[IP];
36
}
37
38
//检测当前HashTable保存的Session有没有已经超时的,有则清除掉
39
private static bool checkSession(string HostAddress)
40
{
41
try
42
{
43
if(DateTime.Compare(DateTime.Now,((DateTime)UserSession[HostAddress+"_time"]).AddMinutes(Session_timeout).AddSeconds(-1))>0)
44
{
45
UserSession.Remove(HostAddress);
46
UserSession.Remove(HostAddress+"_time");
47
return true;
48
}
49
else
50
{
51
return false;
52
}
53
}
54
catch
55
{
56
if(UserSession.ContainsKey(HostAddress))
57
UserSession.Remove(HostAddress);
58
return false;
59
}
60
}
61
62
protected void Session_End(Object sender, EventArgs e)
63
{
64
checkSession(Request.UserHostAddress);
65
}
66
}

2



3

4

5

6

7

8

9



10

11

12

13

14



15

16

17

18

19

20



21

22

23

24

25



26

27

28

29

30

31

32

33

34



35

36

37

38

39

40



41

42



43

44



45

46

47

48

49

50



51

52

53

54

55



56

57

58

59

60

61

62

63



64

65

66

下面是调用代码:
1
public class Service : System.Web.Services.WebService
2

{
3
public Service()
4
{
5
InitializeComponent();
6
7
}
8
组件设计器生成的代码#region 组件设计器生成的代码
9
10
//Web 服务设计器所必需的
11
private IContainer components = null;
12
13
/**//// <summary>
14
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
15
/// 此方法的内容。
16
/// </summary>
17
private void InitializeComponent()
18
{
19
20
}
21
22
/**//// <summary>
23
/// 清理所有正在使用的资源。
24
/// </summary>
25
protected override void Dispose( bool disposing )
26
{
27
if(disposing && components != null)
28
{
29
components.Dispose();
30
}
31
base.Dispose(disposing);
32
}
33
34
#endregion
35
36
private object ReadCurrentSession(string Key)
37
{
38
return Global.mySession(Session["ip"].ToString())[Key];
39
}
40
private void SetCurrentSession(string Key,object Value)
41
{
42
Global.mySession(Session["ip"].ToString())[Key]=Value;
43
}
44
45
//测试方法1:使用Hashtable中保存的Session
46
[WebMethod(EnableSession=true)]
47
public int Add()
48
{
49
int count;
50
if(ReadCurrentSession("count")==null)
51
count=0;
52
else
53
count=Convert.ToInt32(ReadCurrentSession("count"));
54
count++;
55
SetCurrentSession("count",count);
56
return count;
57
}
58
59
//测试方法2:使用系统内建的Session
60
[WebMethod(EnableSession=true)]
61
public int Add2()
62
{
63
int count;
64
if(Session["count2"]==null)
65
count=0;
66
else
67
count=Convert.ToInt32(Session["count2"]);
68
count++;
69
Session["count2"]=count;
70
return count;
71
}
72
}

2



3

4



5

6

7

8


9

10

11

12

13


14

15

16

17

18



19

20

21

22


23

24

25

26



27

28



29

30

31

32

33

34

35

36

37



38

39

40

41



42

43

44

45

46

47

48



49

50

51

52

53

54

55

56

57

58

59

60

61

62



63

64

65

66

67

68

69

70

71

72

经过测试,以上代码完全可行,只是使用的时候要小心,因为同一个IP地址访问Web服务,即使是退出客户端应用程序,换个操作员重新登录,仍然会使用同一个Session,这就需要在服务器端判断,在适当的时候启用新的Session会话.