注意:net.tcp://.....之类的不能通过服务引用来引用,只能在客户端直接配置
类或接口都可以定义服务协议,但建议使用接口,因为接口可以直接对服务协议建模
双工模式总结
双工模式的特点是,无论使用单向消息发送还是请求/答复消息发送方式,服务和客户端均能够独立地向对方发送消息。对于必须直接与客户端通信或向消息交换的任意一方提供异步体验的服务,这种双向通信方式非常有用
-由于存在于客户端通信的附加机制,双向模式比请求/答复或单向模式要略微复杂
-若要实现双工模式,您必须创建第二个接口,该接口包含在客户端调用的方法声明
[
ServiceContract
(Namespace=
"http://www.DoubleService.com"
,CallbackContract=
typeof
(
ICalculator
))]
public
interface
ICalculator
{
[
OperationContract
(IsOneWay =
true
)]
//IsOneWay因为不需要返回值,没有返回值,所以设置为单向模式
void
Addd(
double
x,
double
y);
}
wcf采用基于服务契约的调用形式,客户端正常的服务调用需要服务契约,同理服务端回调客户端依然需要通过描述回调操作的服务契约,我们把这种契约称为回调契约。回调契约的类型通过ServiceContractAttriute特性的callbackContract属性进行制定
上面代码中服务契约ICalculator的回调契约ICallback定义如下。由于回调契约本质也是一个服务契约,所以定义方式和一般意义上的服务契约基本一样。有一点不同的是,由于定义ICalculator的时候已经通过[ServiceContract(CallbackContract=typeof(ICallback))]指明ICallback是一个服务契约了,所以ICallback不再需要添加
ServiceContractAttribute
特性。ICallback定义了一个服务操作DisplayResult用于显示运算结果(前两个参数为执行加法运算的操作数),由于服务端不需要回调的返回值,索性将回调操作也设为单向方法。
步骤二:实现服务
在实现了上面定义的服务契约ICalculator的服务CalculatorService中,实现了Add操作,完成运算和结果显示的工作。结果显示是通过回调的方式实现的,所以需要借助于客户端提供的回调对象(该对象在客户端调用CalculatorService的时候指定,在介绍客户端代码的实现的时候会讲到)。在WCF中,回调对象通过当前
OperationContext的GetCallback<T>方法获得(T代表回调契约的类型)
using
contracts;
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.ServiceModel;
using
System.Text;
using
System.Threading.Tasks;
using
contracts;
namespace
service
{
public
class
CalculatorService
:
ICalculator
{
public
void
Addd(
double
x,
double
y)
{
double
result = x + y;
ICallback
callback =
OperationContext
.Current.GetCallbackChannel<
ICallback
>();
callback.DisplayResult(x, y, result);
}
}
}
在WCF预定义绑定类型中,
WSDualHttpBinding
和
NetTcpBinding
均提供了对双工通信的支持,但是两者在对双工通信的实现机制上却有本质的区别。
WSDualHttpBinding
是基于HTTP传输协议的;而HTTP协议本身是基于请求-回复的传输协议,基于HTTP的通道本质上都是单向的。
WSDualHttpBinding
实际上创建了两个通道,一个用于客户端向服务端的通信,而另一个则用于服务端到客户端的通信,从而间接地提供了双工通信的实现。而
NetTcpBinding
完全基于支持双工通信的TCP协议