这一节大家了解下PerSession实例行为PerSession表示会话实例行为当客户端调用服务器后服务器端会为客户端分配一个新的服务实例这个实例在服务器端SESSION时间过期后将失效客户端每调用一次服务在客户端生成一个新的代理实例都会产生一个新的会话 PerSession实例行为有点类似于ASPNET中的session但又些不同 在WCF中使用PerSession实例需要手动设置行为 [ServiceBehavior(InstanceContextMode=InstanceContextModePerSession)] 默认情况下WCF的实例行为为PerSession 在WCF中并不是所有通信协议都可以使用PerSession实例行为的只有支持会话的通信协议才可以使用PerSession实例如NetTcpBinding NetNamePipeBinding wsHttpBinding wsFederationHttpBindingwsDualHttpBinding PerSession设置 我们看下代码中怎样设置 persession实例行为服务器端契约和行为设置 在契约实现上设置实例行为在契约上设置会话模式 [ServiceContract(SessionMode=SessionModeAllowed)] public interface IPerSession { [OperationContract] int AddCountBySession(); } [ServiceBehavior(InstanceContextMode=InstanceContextModePerSession)] public class PerSessionImpl:IPerSessionIDisposable { private int num; /// <summary> /// 通过 Session模式的方法调用 /// </summary> /// <returns></returns> public int AddCountBySession() { num = num + ; ConsoleWriteLine(当前值:+numToString()+时间:+DateTimeNowToString()); return num; } public void Dispose() { ConsoleWriteLine(释放实例); } } 客户端调用 private void button_Click(object sender EventArgs e) { //PerSession调用方式 ChannelFactory<IPerSession> channelFactory = new ChannelFactory<IPerSession>(WSHttpBinding_IPerSession); IPerSession client = channelFactoryCreateChannel(); //同一个客户端实例调用AddCount方法两次输出的结果一样 clientAddCountBySession(); clientAddCountBySession(); } 在上面的客户端调用代码我们同一个实例调用了两次方法此时发现服务器端变量的值出现递增这是因为这两次调用在同一个会话内 我们多次点击按钮会发现每次点击服务器端的变量值都是从开始递增这是因为每次点击按钮都创建了一个新的代理实例相当于创建了一个新的会话 执行结果如下 我们可以这样理解一个会话在客户端每生成一个代理实例就算一个会话例如上面的IPerSession client = channelFactoryCreateChannel();实例就是一个会话所以调用了AddCountBySession方法两次出现变量值递增的情况 客户端调用 接下来我们在客户端启动的时候创建一个全局实例变量这样连续单击按钮执行多次服务器端的变量值一直会递增因为多次执行都是在一个会话内完成的 private void Form_Load(object sender EventArgs e) { ChannelFactory<IPerSession> channelFactory = new ChannelFactory<IPerSession>(WSHttpBinding_IPerSession); Sessionclient = channelFactoryCreateChannel(); } IPerSession Sessionclient; private void button_Click(object sender EventArgs e) { //定义一个全局session实例进行调用 SessionclientAddCountBySession(); } 执行结果如下 以上代码我们创建了一个全局实例多次点击按钮执行服务器端变量值在同一个会话期内一直递增 Session时效设置 PerSession模式的会话时间是有限制的我们可以手动设置session的会话时间一旦超过了session的有效时间session会自动释放 可以在服务器端的配置文件中的绑定设置中设置会话时间 receiveTimeout=:: 表示会话时间为秒一旦超时服务器就会关闭会话 配置文件如下 <bindings> <wsHttpBinding> <binding name=WSHttpBinding_IPerSession closeTimeout=:: openTimeout=:: receiveTimeout=:: sendTimeout=:: bypassProxyOnLocal=false transactionFlow=false hostNameComparisonMode=StrongWildcard maxBufferPoolSize= maxReceivedMessageSize= messageEncoding=Text textEncoding=utf useDefaultWebProxy=true allowCookies=false> <readerQuotas maxDepth= maxStringContentLength= maxArrayLength= maxBytesPerRead= maxNameTableCharCount= /> <reliableSession ordered=true inactivityTimeout=:: enabled=false /> <security mode=Message> <transport clientCredentialType=Windows proxyCredentialType=None realm= /> <message clientCredentialType=Windows negotiateServiceCredential=true algorithmSuite=Default /> </security> </binding> </wsHttpBinding> </bindings> 通过以上的例子我们知道Persession的优缺点 通过persession可以设置会话的有效期保证服务实例在一定范围内可以重复利用 缺点 使用session模式服务器不能被合理的利用客户端调用完后实例不能立刻释放增加了服务器的压力 |