初学WCF之消息模式3——双工模式

时间:2022-09-01 08:46:08

  昨天终于下定决心计划这个月要把WCF学完,之所以安排一个月的时间,我不要只是学些表面的东西,我要比较深入的去学习下它。如果只学些表面的东西,我想一般的人花个一周的时间就够了。最近一段时间想要学的东西感觉太多了,想学习下Silverlight、WPF、WCF、MVC等,但总感觉好像很忙似的,我也不知道我在忙些什么,就这样稀里糊涂的一天就过去,一事无成。昨天晚上终于想起了5月份写的一个计划规则,还是按照这个计划规则去写每天的计划、日记、月计划。这样每天做了些什么,每天应该做些什么,目标很明确,再也不会像以前那样,想学Silverlight、WPF、WCF、MVC等,一会儿想看下Silverlight,一会儿想看下WPF,一会儿想等找到份工作再去学习它们。像这样下去这些东西的皮毛都没有学到,而且这样又把自己累得要死。 人们总喜欢说计划赶不变化,我觉得这没有什么道理,我觉得只要你计划的合理的话,这个计划肯定不会难产的。这是我最近的状况总结。费话说的有点多了,还大家见谅。。。呵呵!下面主要是和大家分享下我今天所学的双工模式。

  这个其实不难,但让我花比较长的时间,咱天生有点愚笨,没办法,所以特意记录下,以免下次又忘记了。

  双工模式的特点是:无论使用单向消息发送还是请求/答复消息发送方式,服务和客户端均能够独立地向对方发送消息。对于必须直接与客户端通信或向消息交换的任意一方提供异步体验(包括类似于事件的行为)的服务来说,这种双向通信形式非常有用。

  由于存在与客户端通信的附加机制,双工模式比请求/答复或单向模式要略为复杂。

  若要设计为双工协定,还必须设计回调协定,并将该回调协定的类型分配给标记服务协定的ServiceContractAttribute属性(attribute)的CallbackContract属性(protery)。

  若要实现双工模式,您必须创建第二个接口,该接口包含在客户端调用的方法声明。(以上四段话摘自:MSDN Webcasts 徐长龙讲的《跟我一起从零开始学WCF系列课程》的第二章,希望大家能充分理解这四段的意思,我今花了比较长的时间来学这个双工模式,就是因为没有注意看这四段话,没有理解好。)。

  下面我们就来创建一个WCF项目吧!

初学WCF之消息模式3——双工模式

  点击确定,就这样创建了一个WCF项目了。简单吧。。。

目录如下:

初学WCF之消息模式3——双工模式

你把IService1.cs和Serivce1.cs删除了也可以,没事的,咱就懒得删除了。咱把IService1.cs和Serivce1.cs里面的内容全部删除了。以下是IService1.cs文件里的内容:

初学WCF之消息模式3——双工模式

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();
}
}
}

  Demo下载

  欢迎大家拍砖,咱家正在建房......,如果你是烧砖厂的,欢迎你一车砖一车砖的拍,咱高兴的很呐,时间也不早了,明天早上还要去面试,该洗洗睡了,晚安各位基友。。。