标签:
上周微软开公布会说.NET支持全然跨平台和并开放Core源代码的新闻,让我们顿时感到.NET要迎来它的春天。尽管早在几年前.NET就能开发Android和IOS,可是这次的跨平台把Linux都放到了微软战略之中,以后的.NET Developer就能够使用Vs开发Linux应用了,Developer又有了新的选择,从微软的战略转型也能够看出互联网已经步入到了新的模式,以后不再是PC的时代,移动互联和云时代已经到来。
近期做项目时使用到了WCF,项目把数据层和程序层进行了切割,相互之间的传输数据使用的就是WCF,这次的项目是为英国银行Enumis做的一整套银行的系统。从业务上总体划分为e-Banking、Corporate Panel、Etam、e-Commerce它们总体上构成了这家银行的一个网上管理系统,事实上这样的网上系统跟中国的银行是非常类似的,这些系统之间是通过相互之间提供数据或者接口来协同工作。
WCF全称是Windows Communication Fundation,提供了统一的,可用于建立安全、可靠地面向服务的应用的高效开发平台。WCF是基于属性的开发。它统一了各种分布式技术,也就是说它在应用程序和数据之间、应用程序与应用程序之间提供了一个桥梁,通过使用WCF来管理数据之间的互操作。这里说所的统一分布式技术说的是它把Windows中全部的通信技术做了整合封装,把它们都封装到了WCF架构里面。这样不管是採用何种通信方式仅仅须要加入一个WCF服务接口。然后全部基于WCF的应用都能够互相通信。这样增强了程序之间的灵活性。
WCF创建服务时是通过使用属性来指明的,在接口或类的定义上方使用ServiceContract(服务契约)来指明一个服务,在方法定义上方使用OperationContract(方法契约)来指明一则消息。这样就完毕了一个WCF的定义工作,假设使用的是接口那么须要实现对应的接口才可。
详细的定义方法来看以下的演示样例,使用的是接口方式来定义服务契约。
加入一个WCF应用程序集。然后在程序集中加入一个WCF,在加入时Item时能够选择WCF Service这样Vs会依据自带的模板新增一个接口的服务协定,并加入一个新的svc文件来实现接口。这个svc文件就是相应的wcf的实现类。另外也能够手动的编写一个服务协定接口。并实现相应的方法。例如以下代码:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace Contracts { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService2" in both code and config file together. [ServiceContract] public interface IService2 { [OperationContract] string DoWork(); } public class Service2 : IService2 { public string DoWork() { return "Hello WCF!"; } } }
想要使用服务,在程序集中有两种方式,一种是通过加入服务的方法加入指定的服务,另外也能够手动在配置文件里加入终结点来实现服务的加入,
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Threading.Tasks; using Contracts; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { IService2 service = new Service2(); Console.WriteLine(service.DoWork()); Console.Read(); } } }
上节介绍了有关WCF的服务的创建方法,并做了一个小的Demo来演示WCF的创建过程,WCF是採用属性标注开发的,在定义时相当的简单。
接下来我们对消息模式做具体的讨论。WCF提供了三种消息模式,各自是单向模式、请求/回答模式和双工模式,三种模式都支持client向服务端发送消息。不同的是单向模式仅仅支持消息的发送,不支持返回。
请求/回答模式支持client向服务端发送数据,并同一时候等待返回数据,它不支持服务端调用client。
双工模式则比較强大,不仅支持client调用服务端的方法,同一时候也支持服务端调用client的方法,功能强大。
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; namespace WcfService4 { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. [ServiceContract] public interface IService1 { //声明单向模式消息的方法 [OperationContract(IsOneWay = true)] void GetData(); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); // TODO: Add your service operations here } // Use a data contract as illustrated in the sample below to add composite types to service operations. [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } } namespace WcfService4 { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together. // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging. //在一个service中实现WCF的接口协议 public class Service1 : IService1 { public void GetData() { System.Threading.Thread.Sleep(10000); Console.WriteLine("你好哈"); //return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } } } //在client调用该服务,结果该线程并不会停顿而是继续运行client中的方法。 namespace ConsoleApplication1 { class Program { static void Main(string[] args) { ServiceReference1.IService1 service1=new Service1Client(); service1.GetData(); Console.WriteLine("This Main function"); Console.Read(); } } }
client在调用服务的方法后,线程并没有停止请求,而是继续向下运行,这样的请求方式就是单向模式。
这样的模式是WCF消息模式的模式,也就是说client在服务端请求后会等待服务端运行完成并返回给client数据后。client才会继续向下运行。这样的方式相对单向模式来说灵活性差,可是安全性高,由于是单线程的所以安全性极高,适用于有数据返回的请求。
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; namespace WcfService4 { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. [ServiceContract] public interface IService1 { //声明请求/答复模式消息的方法 [OperationContract(IsOneWay = true)] string GetData(); } } namespace WcfService4 { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together. // NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging. //在一个service中实现WCF的接口协议 public class Service1 : IService1 { public string GetData() { System.Threading.Thread.Sleep(10000); Console.WriteLine("你好哈"); return string.Format("You apply the WCF!"); } } } //在client调用该服务,结果该线程会依据WCF消息线程的时间停顿,当停顿完毕后才会继续向下运行。 namespace ConsoleApplication1 { class Program { static void Main(string[] args) { ServiceReference1.IService1 service1=new Service1Client(); service1.GetData(); Console.WriteLine("This Main function"); Console.Read(); } } }
双工模式相交前两种模式来说相对复杂,它的请求方式同一时候适用于client和服务端,也就是说client能够请求服务端另外服务端也请求client,它们的调用关系是相互的,也就是client请求服务端的方法后,服务端同一时候请求client进行数据的交换这样的方法就须要使用双工模式。
也就是说双工模式同一时候附加了服务端与client的通信机制。在定义双工模式时须要在服务端指定一个回调函数(使用CallBackContract属性)同一时候定义两个接口。一个是服务端的消息接口,另外一个是client须要实现的接口(即:服务端的回调方法)。
服务端须要实现服务的接口,client须要实现client的服务协定接口。
定义双工服务。在定义时同一时候也要定义回调服务,也就是在client实现的服务,也就是说在声明服务时须要使用CallbackContract来指定回调的协定类,另外也要定义回话的模式,须要使用SessionMode.Required也就是必须使用回话的意思。详细定义方法例如以下:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace Service { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. [ServiceContract(SessionMode = SessionMode.Required,CallbackContract = typeof(ICallBack))] public interface IService1 { [OperationContract] string ApplyData(int value); } public interface ICallBack { [OperationContract] string GetData(string data); } }
using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Runtime.Remoting.Contexts; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace Service { // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together. [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)] public class Service1 : IService1 { public string ApplyData(int value) { ICallBack callBack = OperationContext.Current.GetCallbackChannel<ICallBack>(); string strPrint=callBack.GetData("hahha"); return string.Format("You applyed the data is:{0},we getted data is: {1}",strPrint, value); } } }
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Threading.Tasks; using ConsoleApplication1.ServiceReference1; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { CallBack callBack=new CallBack(); InstanceContext instanceContext=new InstanceContext(callBack); IService1 service1=new Service1Client(instanceContext); string strPrint=service1.ApplyData(32); Console.WriteLine(strPrint); Console.Read(); } } public class CallBack : ServiceReference1.IService1Callback { public string GetData(string data) { return data; } } }
Note1:绑定方式
在建立双工协定时一定要注意使用支持双工协定的绑定,默认的basicHttpBinding绑定方式并不支持双工协定,所以在client加入双工服务协定时就会出错。找不到协议定义的接口。
能够使用wsDualHttpBinding绑定。在服务的终结点中声明绑定方法。绑定方法例如以下:
<endpoint address="" binding="wsDualHttpBinding" contract="Service.IService1">
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)] public class CalculatorService : ICalculator { //省略实现 } [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] public class CalculatorService : ICalculator { //省略实现 }
本系列文章主要是来高速的入门学习WCF的应用,所以有些地方讲的较详细,不须要的能够略过。本文主要从WCF的基础開始重点介绍了WCF的一些术语及WCF三种主要的消息模式。这三种模式个有自己的优缺点,在使用时要依据详细情况详细分析。
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/5153561.html