WCF - Session 剖析

WCF中的Session

      WCF是MS基于SOA建立的一套在分布式环境中各个相对独立系统进行通信的构架,实现了最新的基于WS-*规范。按照SOA的原则,相对独自的业务逻辑以service的形式封装,调用者通过Messaging的方式调用Service。对于承载着某个业务功能的实现的Service应该具有上下文无关性,也就是说个构成Service的operation不应该绑定到具体的调用上下文。因为SOA的一个最大的目标就是尽可能地实现重用,只有具有上下文无关性,Service才能实现最大限度的重用。WCF中Session属于Service Contract的范畴,是一个相对抽象的概念,并在Service Contract定义中通过SessionModel参数来实现。Session的创建和结束都有来自Client端的调用来实现。

如何实现和维护Session?

      Client不能和Service进行直接交互,只能通过客户端创建的Proxy来间接地实现和service的交互,WCF在创建具体的Service Instance时会构建相关的Instance Context。我们可以制定Service的Instance context model。不同的Instance Context Mode体现为Proxy、Service 调用和Service Instance之间的对应关系,Instance Context Mode决定着不同的Session表现。在WCF中,支持以下3中不同类型的Instance Context Mode:

  • PerCall:WCF为每个Serivce调用创建 一个Service Instance,调用完成后回收该Instance。
  • PerSession:在Session期间的所有Service调用绑定到某一个Service Instance,Session被终止后,Service Instance被回收。
  • Singleton:为具体的Service type进行Host的时候,与之对应的Service Instance就被创建出来,此后所有的Service调用都被关联到该Instance。
ContractedBlock.gif ExpandedBlockStart.gif PerCall
  1 //IService
2 [ServiceContract]
3 public interface ICalculatorService
4 {
5 [OperationContract(IsOneWay = true)]
6 void PerCall(double x, double y);
7 [OperationContract]
8 double PerSession(double x, double y);
9 [OperationContract]
10 double Singleton(double x, double y);
11
16 }
17 //Service
18 public class CalculatorService : ICalculatorService
19 {
20 #region Constructor
21 public CalculatorService()
22 {
23 Console.WriteLine("Create Service Instance:Current session ID is: {0}", OperationContext.Current.SessionId);
24 }
25 #endregion
26
27 #region Destructor
28 ~CalculatorService()
29 {
30 Console.WriteLine("Destory Service Instance:Current session ID is: {0}", OperationContext.Current.SessionId);
31 }
32 #endregion
33
34 #region Result
35 private double _result;
36 public double Result
37 {
38 get
39 {
40 return _result;
41 }
42 }
43 #endregion
44
45 #region ICalculator Members
46
47 public void PerCall(double x, double y)
48 {
49 _result += x + y;
50 Console.WriteLine("PerCall:Current session ID is: {0}", OperationContext.Current.SessionId);
51 Console.WriteLine("Current result is {0}", _result.ToString());
52 }
53
54 public double PerSession(double x, double y)
55 {
56 _result += x + y;
57 Console.WriteLine("PerSession:Current session ID is: {0}", OperationContext.Current.SessionId);
58 Console.WriteLine("Current result is {0}", _result.ToString());
59 return _result;
60 }
61
62 public double Singleton(double x, double y)
63 {
64 _result += x + y;
65 Console.WriteLine("Singleton:Current session ID is: {0}", OperationContext.Current.SessionId);
66 Console.WriteLine("Current result is {0}", _result.ToString());
67 return _result;
68 }
69
78
79 #endregion
80 }
81
82 //Host httpBasicBinding
83 using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
84 {
85 Console.Title = "WCF Service Host: Session";
86 host.Opened += delegate
87 {
88 Console.WriteLine("Calculator service has been host");
89 };
90 host.Open();
91 Console.Read();
92 }
93
94 //Client httpBasicBinding

95 Console.Title = "WCF Session: Client";
96
97 ChannelFactory<ICalculatorService> channelFactory = new ChannelFactory<ICalculatorService>("CalculatorServiceEndpoint");
98 ICalculatorService channel = channelFactory.CreateChannel();
99 try
100 {
101 channel.PerCall(1, 1);
102 Console.WriteLine("Channel PerCall 1");
103 channel.PerCall(1, 1);
104 Console.WriteLine("Channel PerCall 2");
105 }
106 catch (Exception ex)
107 {
108 Console.WriteLine("Channel Exception:" + ex.Message);
109 }
110 (channel as ICommunicationObject).Close();
111
112 ICalculatorService channel2 = channelFactory.CreateChannel();
113 try
114 {
115 channel2.PerCall(1, 1);
116 Console.WriteLine("Channel2 PerCall 1");
117 channel2.PerCall(1, 1);
118 Console.WriteLine("Channel2 PerCall 2");
119 }
120 catch (Exception ex)
121 {
122 Console.WriteLine("Channel2 Exception:" + ex.Message);
123 }
124 (channel2 as ICommunicationObject).Close();
125 Console.Read();

 

ContractedBlock.gif ExpandedBlockStart.gif PerSession Demo
  1 //IService
2 [ServiceContract(SessionMode = SessionMode.Required)]
3 public interface ICalculatorService
4 {
5 [OperationContract]
6 void PerCall(double x, double y);
7 [OperationContract]
8 double PerSession(double x, double y);
9 [OperationContract]
10 double Singleton(double x, double y);
11
12 }
13
14
15 //Service
16 public class CalculatorService : ICalculatorService
17 {
18 #region Constructor
19 public CalculatorService()
20 {
21 Console.WriteLine("Create Service Instance:Current session ID is: {0}", OperationContext.Current.SessionId);
22 }
23 #endregion
24
25 #region Destructor
26 ~CalculatorService()
27 {
28 Console.WriteLine("Destory Service Instance:Current session ID is: {0}", OperationContext.Current.SessionId);
29 }
30 #endregion
31
32 #region Result
33 private double _result;
34 public double Result
35 {
36 get
37 {
38 return _result;
39 }
40 }
41 #endregion
42
43 #region ICalculator Members
44
45 public void PerCall(double x, double y)
46 {
47 _result += x + y;
48 Console.WriteLine("PerCall:Current session ID is: {0}", OperationContext.Current.SessionId);
49 Console.WriteLine("Current result is {0}", _result.ToString());
50 }
51
52 public double PerSession(double x, double y)
53 {
54 _result += x + y;
55 Console.WriteLine("PerSession:Current session ID is: {0}", OperationContext.Current.SessionId);
56 Console.WriteLine("Current result is {0}", _result.ToString());
57 return _result;
58 }
59
60 public double Singleton(double x, double y)
61 {
62 _result += x + y;
63 Console.WriteLine("Singleton:Current session ID is: {0}", OperationContext.Current.SessionId);
64 Console.WriteLine("Current result is {0}", _result.ToString());
65 return _result;
66 }
67
68 #endregion
69 }
70
71
72 //Host
73 using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
74 {
75 Console.Title = "WCF Service Host: Session";
76 host.Opened += delegate
77 {
78 Console.WriteLine("Calculator service has been host");
79 };
80 host.Open();
81 Console.Read();
82 }
83
84 //Client
85 Console.Title = "WCF Session: Client";
86
87 ChannelFactory<ICalculatorService> channelFactory = new ChannelFactory<ICalculatorService>("CalculatorServiceEndpoint")
88 ICalculatorService channel = channelFactory.CreateChannel();
89 try
90 {
91 double retValue = 0;
92 retValue = channel.PerSession(1, 1);
93 Console.WriteLine(string.Format("Channel PerCall 1,reback value is {0}",retValue.ToString()));
94 retValue = channel.PerSession(1, 1);
95 Console.WriteLine(string.Format("Channel PerCall 1,reback value is {0}", retValue.ToString()));
96 }
97 catch (Exception ex)
98 {
99 Console.WriteLine("Channel Exception:" + ex.Message);
100 }
101 (channel as ICommunicationObject).Close();
102
103 ICalculatorService channel2 = channelFactory.CreateChannel();
104 try
105 {
106 double retValue = 0;
107 retValue = channel2.PerSession(1, 1);
108 Console.WriteLine(string.Format("Channel PerCall 2,reback value is {0}", retValue.ToString()));
109 retValue = channel2.PerSession(1, 1);
110 Console.WriteLine(string.Format("Channel PerCall 2,reback value is {0}", retValue.ToString()));
111 }
112 catch (Exception ex)
113 {
114 Console.WriteLine("Channel2 Exception:" + ex.Message);
115 }
116 (channel2 as ICommunicationObject).Close();
117 Console.Read();

 

转载于:https://www.cnblogs.com/fangrobert/archive/2011/09/21/2160146.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值