标签:
上周微软开公布会说.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