老老实实学WCF

第七篇 会话

通过前几篇的学习,我们已经掌握了WCF的最基本的编程模型,我们已经可以写出完整的通信了。从这篇开始我们要深入地了解这个模型的高级特性,这些特性用来保证我们的程序运行的高效、稳定和安全。

首先我们来学习会话。

1. 什么是会话

会话是通信双方进行通信的一个时间片、一个语境或者说一个上下文,在这个特定的环境中,通信的双方是彼此认识的,就像两个人在聊天,他们都很清楚谁在聆听自己讲话,也很清楚对方讲的话是给自己听的,简单的说就是通信双方是可以记住彼此的。

一旦会话结束了,通信双方就忘记了彼此,即使他们再次建立会话,他们也不会记得他们上次会话的内容,也就是他们不记得他们曾经见过面。

这在我们现实世界中或许很难想象,但是在通信的世界里就是这样的。服务端不可能记住每个跟他通信的人,他只能在一段时间内(会话)记住一个人。

这个特性是很有用的,有些逻辑需要客户端和服务端通信多次才能完成,在这个期间双方需要记住彼此,而且会话也是很多其他特性实现的基础,例如双工通信。

2. 如何建立会话

那么我们要想建立一个会话通信,应该具备怎样的条件呢?

(1) 需要支持会话的绑定。绑定描述了双方的通信方式,不同的绑定对会话的支持是不同的,比如basicHttpBinding是不支持会话的,而wsHttpBinding就是支持的。要建立会话通信,这个通信必须首先使用支持会话的绑定。

(2) 让服务协定支持会话,服务协定实际上就是通信的通道(见第四、五篇),让服务协定支持会话,那么就可以在这个通信通道上支持会话了。

选择支持会话的绑定我们知道怎么做,可如何让服务协定支持会话呢?要用到在修饰服务协定的SeviceContract属性, 我们知道被这个属性修饰的接口是一个服务协定,其实这个属性也拥有属性,其中一个属性叫做SessionMode。这是一个枚举,我们通过设置这个枚举的 值来配置服务协定是否支持会话。例如:

  1. [ServiceContract(SessionMode = SessionMode.Required)]
  2. public interface IHelloWCF
  3. {
  4. [OperationContract]
  5. string HelloWCF();
  6. }

这段代码中,我把SessionMode设置为了Required,这表示调用这个服务协定的客户端必须使用会话。

SessionMode有三个可能的值:

1) Allowed:这是默认值,表示这个服务协定是允许会话的,客户端可以选择用会话连接,也可以选择不用会话连接。

2) Required:表示服务协定要求客户端连接必须使用会话。

3) NotAllowed:表示服务协定不允许使用会话连接。

这些配置需要搭配其他的配置才能起到实际意义,比如服务实例模式,服务端和客户端调用模式等等,等我们了解到这些特性的时候再展开,现在我们只需要知道,前两种配置是支持会话的,第三种是不支持的。

3. 一个简单的例子

我们通过一个简单的例子来看看允许会话与不允许的区别,我修改了前几篇中寄存在IIS中的服务,代码如下:

  1. using System;
  2. using System.ServiceModel;
  3. namespace LearnWCF
  4. {
  5. [ServiceContract(SessionMode = SessionMode.Allowed)]
  6. public interface IHelloWCF
  7. {
  8. [OperationContract]
  9. string HelloWCF();
  10. }
  11. public class HelloWCFService : IHelloWCF
  12. {
  13. private int _Counter;
  14. public string HelloWCF()
  15. {
  16. _Counter++;
  17. return "Hello, you called " + _Counter.ToString() + " time(s)";
  18. }
  19. }
  20. }

首先我们把服务协定的会话模式设置为允许会话(Allowed),在服务实现中,我为服务实现类定义了一个计数器成员,每次调用都会将这个计数器加一,然后返回一句话告诉客户端调用了多少次。

服务端的配置文件如下:

  1. <configuration>
  2. <system.serviceModel>
  3. <services>
  4. <service name="LearnWCF.HelloWCFService" behaviorConfiguration="metadataExchange">
  5. <endpoint address="" binding="wsHttpBinding" contract="LearnWCF.IHelloWCF"/>
  6. <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  7. </service>
  8. </services>
  9. <behaviors>
  10. <serviceBehaviors>
  11. <behavior name="metadataExchange">
  12. <serviceMetadata httpGetEnabled="true" />
  13. </behavior>
  14. </serviceBehaviors>
  15. </behaviors>
  16. </system.serviceModel>
  17. </configuration>

在这里我配置了支持会话的wsHttpBinding。

客户端的调用代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace ConsoleApplication2
  6. {
  7. class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11. ConsoleApplication2.ServiceReference1.HelloWCFClient client = new ServiceReference1.HelloWCFClient();
  12. Console.WriteLine(client.HelloWCF());
  13. Console.WriteLine(client.HelloWCF());
  14. client.Close();
  15. Console.Read();
  16. }
  17. }
  18. }

就是连续调用两次服务端的方法并输出结果。

F5运行一下,会看到下面的结果:

我们看到提示调用了两次,也就是说服务端记住了客户端,当他第二次调用的时候将将计数器加一,就返回了调用两次。当然这个局面的形成还受到实例上下文模式为PerSession的影响,我们后面会展开,总之服务协定支持会话,才出现了这个局面。

如果我们把SessionMode改成NotAllowed,其他不改动,结果就会是下面的样子:

结果两次都是1,说明服务器在第二次受到调用的时候已经忘记了之前那个客户端,他又分配了一个新的计数器给这个客户端,所以计数就总是1了。

其实这个例子是很粗糙的,这里面还有些其他的影响因素,我们就是通过这个例子来看看SessionMode的一方面影响。

4. 总结

这一篇的内容比较少,我们应该记住一些要点,在以后接触更多特性的时候才不会混淆。

(1) 是否支持会话首先取决于选择的绑定。

(2) 是否支持会话通过配置服务协定的ServiceContract属性的SessionMode属性实现的。

[老老实实学WCF] 第七篇 会话的更多相关文章

  1. [老老实实学WCF] 第十篇 消息通信模式(下) 双工

    老老实实学WCF 第十篇 消息通信模式(下) 双工 在前一篇的学习中,我们了解了单向和请求/应答这两种消息通信模式.我们知道可以通过配置操作协定的IsOneWay属性来改变模式.在这一篇中我们来研究双 ...

  2. [老老实实学WCF] 第八篇 实例化

    老老实实学WCF 第八篇 实例化 通过上一篇的学习,我们简单地了解了会话,我们知道服务端和客户端之间可以建立会话连接,也可以建立非会话连接,通信的绑定和服务协定的 ServiceContract 的S ...

  3. [老老实实学WCF] 第六篇 元数据交换

    老老实实学WCF 第六篇 元数据交换 通过前两篇的学习,我们了解了WCF通信的一些基本原理,我们知道,WCF服务端和客户端通过共享元数据(包括服务协定.服务器终结点信息)在两个 终结点上建立通道从而进 ...

  4. [老老实实学WCF] 第五篇 再探通信--ClientBase

    老老实实学WCF 第五篇 再探通信--ClientBase 在上一篇中,我们抛开了服务引用和元数据交换,在客户端中手动添加了元数据代码,并利用通道工厂ChannelFactory<>类创 ...

  5. [老老实实学WCF] 第四篇 初探通信--ChannelFactory

    老老实实学WCF 第四篇 初探通信--ChannelFactory 通过前几篇的学习,我们简单了解了WCF的服务端-客户端模型,可以建立一个简单的WCF通信程序,并且可以把我们的服务寄宿在IIS中了. ...

  6. [老老实实学WCF] 第三篇 在IIS中寄存服务

    老老实实学WCF 第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我 ...

  7. (转) [老老实实学WCF] 第三篇 在IIS中寄存服务

    第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我们对WCF的编程生 ...

  8. (转)[老老实实学WCF] 第四篇 初探通信--ChannelFactory

    第四篇 初探通信--ChannelFactory 通过前几篇的学习,我们简单了解了WCF的服务端-客户端模型,可以建立一个简单的WCF通信程序,并且可以把我们的服务寄宿在IIS中了.我们不禁感叹WCF ...

  9. 我们一起学习WCF 第七篇会话模式

    会话:就是客户端和服务端之间的谈话.比喻A和B去登陆网站,那么A用户登陆进去肯定显示A的用户详情,那么这就是A和服务器之间的交流.同样B用户登陆之后显示B的详情,这就表示这是B和服务器之间的交流. 如 ...

随机推荐

  1. 今天弱爆了,svn创建项目

    今天弱爆了 1.再svnRoot下新建你要建的项目名如:hqdj  文件夹,然后选中它点击右键选中create repository here... ,选择文件系统类型 2.进入conf文件夹进行配置 ...

  2. Delphi开发OCX详细步骤总结

     首先要弄明白你要写的OCX是用在客户端还是用在服务器端    假如用在客户端: 1.创建  打开delphi 7,选择菜单"new"->"other"- ...

  3. linux脚本^M: bad interpreter:解决方法

    转自:http://blog.csdn.net/huiguixian/article/details/6386774 在Linux中执行.sh脚本,异常提示/bin/sh^M: bad interpr ...

  4. Codeforces Round #250 (Div. 2)——The Child and Set

    题目链接 题意: 给定goal和limit,求1-limit中的若干个数,每一个数最多出现一次,且这些数的lowbit()值之和等于goal,假设存在这种一些数,输出个数和每一个数:否则-1 分析: ...

  5. cocos2d-html5的jsb模式下如何在编译时自动将js编译为jsc

    cocos2d-html5是一个用JS来开发游戏的框架,通过javascript Binding的方式可以将游戏编译到手机上.这对前端开发人员来说非常方便,开发效率也比使用c++开发要快的多. jsb ...

  6. Reservoir Sampling - 蓄水池抽样

    问题起源于编程珠玑Column 12中的题目10,其描述如下: How could you select one of n objects at random, where you see the o ...

  7. 编译linux内核以及depmod的使用

    转载:http://blog.lmtw.com/b/18215/archives/2010/71074.html depmod(depend module) 功能说明:分析可载入模块的相依性. 语 法 ...

  8. Linux 混杂设备、外部中断和输入子系统

    混杂设备也是一种字符设备,主设备号固定为10.相对于普通字符设备驱动,它不需要自己去生成设备文件. 1.声明使用的头文件 #include <linux/miscdevice.h> 2.定 ...

  9. Transact-SQL三值逻辑

    /*===========================<一>========================== 在SQL中逻辑表达式的值有三种: 1.TRUE 2.FALSE 3.U ...

  10. org.apache.hadoop.conf-Configuration

    终于遇到第一块硬骨头 Hadoop没有使用java.util.Properties管理配置文件,而是自己定义了一套配置文件管理系统和自己的API. package org.apache.hadoop. ...