初学WCF之消息模式3——双工模式
昨天终于下定决心计划这个月要把WCF学完,之所以安排一个月的时间,我不要只是学些表面的东西,我要比较深入的去学习下它。如果只学些表面的东西,我想一般的人花个一周的时间就够了。最近一段时间想要学的东西感觉太多了,想学习下Silverlight、WPF、WCF、MVC等,但总感觉好像很忙似的,我也不知道我在忙些什么,就这样稀里糊涂的一天就过去,一事无成。昨天晚上终于想起了5月份写的一个计划规则,还是按照这个计划规则去写每天的计划、日记、月计划。这样每天做了些什么,每天应该做些什么,目标很明确,再也不会像以前那样,想学Silverlight、WPF、WCF、MVC等,一会儿想看下Silverlight,一会儿想看下WPF,一会儿想等找到份工作再去学习它们。像这样下去这些东西的皮毛都没有学到,而且这样又把自己累得要死。 人们总喜欢说计划赶不变化,我觉得这没有什么道理,我觉得只要你计划的合理的话,这个计划肯定不会难产的。这是我最近的状况总结。费话说的有点多了,还大家见谅。。。呵呵!下面主要是和大家分享下我今天所学的双工模式。
这个其实不难,但让我花比较长的时间,咱天生有点愚笨,没办法,所以特意记录下,以免下次又忘记了。
双工模式的特点是:无论使用单向消息发送还是请求/答复消息发送方式,服务和客户端均能够独立地向对方发送消息。对于必须直接与客户端通信或向消息交换的任意一方提供异步体验(包括类似于事件的行为)的服务来说,这种双向通信形式非常有用。
由于存在与客户端通信的附加机制,双工模式比请求/答复或单向模式要略为复杂。
若要设计为双工协定,还必须设计回调协定,并将该回调协定的类型分配给标记服务协定的ServiceContractAttribute属性(attribute)的CallbackContract属性(protery)。
若要实现双工模式,您必须创建第二个接口,该接口包含在客户端调用的方法声明。(以上四段话摘自:MSDN Webcasts 徐长龙讲的《跟我一起从零开始学WCF系列课程》的第二章,希望大家能充分理解这四段的意思,我今花了比较长的时间来学这个双工模式,就是因为没有注意看这四段话,没有理解好。)。
下面我们就来创建一个WCF项目吧!
点击确定,就这样创建了一个WCF项目了。简单吧。。。
目录如下:
你把IService1.cs和Serivce1.cs删除了也可以,没事的,咱就懒得删除了。咱把IService1.cs和Serivce1.cs里面的内容全部删除了。以下是IService1.cs文件里的内容:
namespace WcfServiceLibrary4 { [ServiceContract(Namespace = "http://Microsoft.ServiceMode.Samples", SessionMode = SessionMode.Required, CallbackContract = typeof(IB))] //定义一个服务接口 public interface IA { [OperationContract(IsOneWay=true)] void Clear(); } //这个是服务端调用客户端里方法的一个接口,在客户端里写一个类继承这个接口时,你是找到不IB这个接口的名字的,上面的CallbackContract = typeof(IB)这句话指定的回调的接口是IB,但它是以IACallback的形式出现的 public interface IB { [OperationContract(IsOneWay=true)] void E(double e); } }
以下是Serivce1.cs里面的代码:
namespace WcfServiceLibrary4 { [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)] public class A : IA { double result; //声明一个IB接口的对象 IB ib = null; //A类的构造方法 public A() { result = 0.0D; //实例化一个IB ib = OperationContext.Current.GetCallbackChannel<IB>(); } public void Clear() { //服务端调用客户端的E方法 ib.E(result + 9); } } }
然后把App.config配置文件修改下就可以了。
本来是这样的:
<service name="WcfServiceLibrary4.Service1" behaviorConfiguration="WcfServiceLibrary4.Service1Behavior"> <host> <baseAddresses> <add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary4/Service1/" /> </baseAddresses> </host> <!-- Service Endpoints --> <!-- 除非完全限定,否则地址将与上面提供的基址相关 --> <endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary4.IService1">
修改后:
<service name="WcfServiceLibrary4.A" behaviorConfiguration="WcfServiceLibrary4.Service1Behavior"> <host> <baseAddresses> <add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary4/A/" /> </baseAddresses> </host> <!-- Service Endpoints --> <!-- 除非完全限定,否则地址将与上面提供的基址相关 --> <endpoint address ="" binding="wsDualHttpBinding" contract="WcfServiceLibrary3.IA">
一定要把wsHttpBinding改成wsDualHttpBinding,请大家仔细对照下。
下面实现客户端的调用吧,不过端还得实现服务端IB的接口。
我在这个项目里添加了个命令项目,你添加个WebFrom项目或者Windows项目也可以的。
哦,差点忘了应该先生成下服务,然后再在命令项目里右击“引用”选择“添加服务引用",不要点错了哦。
然后我们开始在Program.cs里添加如下代码:
//请记得添加以下两个命名空间 using System.ServiceModel; using ConsoleApplication1.ServiceReference1; namespace ConsoleApplication1 { /// <summary> /// 我今天主要是在B继承一个接口这个花了很长的时间,我总以为能找到服务端里的IB接口,谁知道服务端的接口IB是IACallback的形式出现在客户端 /// </summary> public class B:IACallback { #region IACallback 成员 //实现了IB接口的E方法 public void E(double e1) { Console.WriteLine("E:" + e1); }#endregion } class Program { static void Main(string[] args) { InstanceContext instanceContext = new InstanceContext(new B()); ServiceReference1.AClient client = new AClient(instanceContext); client.Clear(); Console.ReadKey(); } } }
欢迎大家拍砖,咱家正在建房......,如果你是烧砖厂的,欢迎你一车砖一车砖的拍,咱高兴的很呐,时间也不早了,明天早上还要去面试,该洗洗睡了,晚安各位基友。。。
本文来自博客园,作者:追夢,转载请注明原文链接:https://www.cnblogs.com/koeltp/archive/2012/07/09/2583807.html