wcf 基础知识 之 消息交换模式 response/reply oneway deplex

wcf支持请求-回复(response-reply)、单工(oneway)以及双工(duplex)三种消息交换模式。今天我们来说一下第一种消息交换模式--请求--回复,请注意这里是消息交换模式。

请求-回复消息交换模式是默认的wcf通信方式,如果我们不显式的设定消息交换模式,那么它就是response-reply模式。这和我们通过浏览器访问一个网址的原理是一致的,客户端发起一个请求,然后客户端等待服务器的响应,服务端处理完成返回结果,在客户端显示,如果超时,浏览器会提示无法显示页面的错误。其实原理是一致的,并且如果采用http作为传输协议的话,可以说没有任何的区别。

 1 namespace Chinaer.WcfDemo.Contracts  2 {  3  [ServiceContract()]  4     public interface ICalculator  5  {  6         [OperationContract(IsOneWay=false)]  7         void Divide(double x, double y);  8  }  9 

10     public interface ICalculatorCallBack 11  { 12         [OperationContract(IsOneWay=false)] 13         void CallBack(string strMessage); 14  } 15 }

我们定义了一个服务契约,里面有一个服务操作Divide,我们显式的设定isOneWay为false,那么它就是通过请求-回复模式进行工作的,或者说我们可以不设定这个值也是一样的。我们首先来看一下这个服务的wsdl是什么样子的把。

 1 <?xml version="1.0" encoding="utf-8" ?> 

 2 - <wsdl:definitions name="CalculatorService" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">

 3 - <wsp:Policy wsu:Id="WSDualHttpBinding_ICalculator_policy">

 4 - <wsp:ExactlyOne>

 5 - <wsp:All>

 6 - <wsrm:RMAssertion xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">

 7   <wsrm:InactivityTimeout Milliseconds="600000" /> 

 8   <wsrm:AcknowledgementInterval Milliseconds="200" /> 

 9   </wsrm:RMAssertion>

 10 - <sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">

 11 - <wsp:Policy>

 12 - <sp:ProtectionToken>

 13 - <wsp:Policy>

 14 - <sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">

 15 - <wsp:Policy>

 16   <sp:RequireDerivedKeys /> 

 17 - <sp:BootstrapPolicy>

 18 - <wsp:Policy>

 19 - <sp:SignedParts>

 20   <sp:Body /> 

 21   <sp:Header Name="ChannelInstance" Namespace="http://schemas.microsoft.com/ws/2005/02/duplex" /> 

 22   <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" /> 

 23   <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" /> 

 24   <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" /> 

 25   <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" /> 

 26   <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" /> 

 27   <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" /> 

 28   <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" /> 

 29   </sp:SignedParts>

 30 - <sp:EncryptedParts>

 31   <sp:Body /> 

 32   </sp:EncryptedParts>

 33 - <sp:SymmetricBinding>

 34 - <wsp:Policy>

 35 - <sp:ProtectionToken>

 36 - <wsp:Policy>

 37 - <sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">

 38 - <wsp:Policy>

 39   <sp:RequireDerivedKeys /> 

 40   </wsp:Policy>

 41   </sp:SpnegoContextToken>

 42   </wsp:Policy>

 43   </sp:ProtectionToken>

 44 - <sp:AlgorithmSuite>

 45 - <wsp:Policy>

 46   <sp:Basic256 /> 

 47   </wsp:Policy>

 48   </sp:AlgorithmSuite>

 49 - <sp:Layout>

 50 - <wsp:Policy>

 51   <sp:Strict /> 

 52   </wsp:Policy>

 53   </sp:Layout>

 54   <sp:IncludeTimestamp /> 

 55   <sp:EncryptSignature /> 

 56   <sp:OnlySignEntireHeadersAndBody /> 

 57   </wsp:Policy>

 58   </sp:SymmetricBinding>

 59 - <sp:Wss11>

 60   <wsp:Policy /> 

 61   </sp:Wss11>

 62 - <sp:Trust10>

 63 - <wsp:Policy>

 64   <sp:MustSupportIssuedTokens /> 

 65   <sp:RequireClientEntropy /> 

 66   <sp:RequireServerEntropy /> 

元数据有点长,但是不影响我们阅读。我们可以看到服务契约对应的是<portType>节点了,<portType>节点具有一系列的operation子元素表示定义在服务契约中的方法,而表示操作的<operation>节点通过输入<input>消息和输出<output>消息的有序组合来描述消息交换模式。

1 -<wsdl:portType name="IName">

2 -<wsdl:operation name="Write">

3 <wsdl:input message="tns:IName_Write_InputMessage" wsaw:Action="http://tempuri.org/IName/Write"/>

4 <wsdl:output message="tns:IName_Write_OutputMessage" wsaw:Action="http://tempuri.org/IName/WriteResponse"/></wsdl:operation></wsdl:portType>

 

 请求-回复消息模式通过operation节点的input和output元素来表示请求-回复的输入和输出消息。

 

void返回值,我们可以看到对于双工通信我们一般定义isOneWay为true,并且返回值为void,当然这里介绍的不是双工通信,所以我们来看一下返回值为void时,输入与输出又是什么呢?

对于请求-回复模式,输入参数列表决定了输入消息的格式,而输出消息的格式则由返回值的类型决定。对于void类型,因为只有输入没有返回值,但是wcf在请求-回复模式下依然会有返回值,只不过返回值的body 为空。

1 -<sp:EncryptedParts>

2 <sp:Body/>

3 </sp:EncryptedParts>

所以说在wcf中即使为void,也是要返回消息的,只不过消息主题部分为空。

还有一种形式就是out和ref 作为方法参数,wcf的消息会怎么样呢?其实想想 没事的时候想想怎些问题,还真是挺有趣的。

这个我们一起来探讨一下,

1 namespace Chinaer.WcfDemo.Contracts 2 { 3  [ServiceContract] 4     public interface IName 5  { 6  [OperationContract] 7         void Write(out string name); 8  } 9 }
 1 namespace Chinaer.WcfDemo.Services  2 {  3    public class Name:IName  4  {  5         public void Write(out string name)  6  {  7             name = "guozhiiq";  8  }  9  } 10 }
 1 <?xml version="1.0" encoding="utf-8"?>

 2 <xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 3   <xs:element name="Write">

 4     <xs:complexType>

 5       <xs:sequence />

 6     </xs:complexType>

 7   </xs:element>

 8   <xs:element name="WriteResponse">

 9     <xs:complexType>

10       <xs:sequence>

11         <xs:element minOccurs="0" name="name" nillable="true" type="xs:string" />

12       </xs:sequence>

13     </xs:complexType>

14   </xs:element>

15 </xs:schema>

 

 

请注意wsdl的格式,portType节点下依然有输出和输入两个子节点,但是是作为参数parameter进行传递的。我们把out换成ref看看是什么结果呢?

 

 1 <?xml version="1.0" encoding="utf-8"?>

 2 <xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">

 3   <xs:element name="Write">

 4     <xs:complexType>

 5       <xs:sequence>

 6         <xs:element minOccurs="0" name="name" nillable="true" type="xs:string" />

 7       </xs:sequence>

 8     </xs:complexType>

 9   </xs:element>

10   <xs:element name="WriteResponse">

11     <xs:complexType>

12       <xs:sequence>

13         <xs:element minOccurs="0" name="name" nillable="true" type="xs:string" />

14       </xs:sequence>

15     </xs:complexType>

16   </xs:element>

17 </xs:schema>

 

各位看到out和ref的区别了吗?

服务契约中的操作只有输入和输出的概念,输入参数作为操作的输入,而输出参数和返回值作为操作的输出,而引用参数同时作为输入和输出。

这让我想到了一个概念,契约的等效性,什么是等效呢?不是说在.Net中定义的数据类型以及名称完全一样就可能称为等效?而是在生成的soap消息中的结构完全相同我们才成为等效。或者说生成的xml相同才是等效。我们可以利用attribute来更改属性在生成xml的name值,不是吗?

在上一篇博客wcf基础知识之 查看soap消息 TcpTrace,我有说到tcpTrace查看soap消息,其实还有其他更加简单的方法,当然这只能是在特殊场合下才可以使用。

如果你的宿主程序是svc,那么恭喜你,你可以不需要通过tcpTrace来查看soap消息了,在添加了服务引用以后,我们可以通过查看代码

wcf 基础知识 之 消息交换模式 response/reply oneway deplex

 

通过查看对应服务的xml代码可以查看到soap消息,其实和tcpTrace截获的差不多,当然没有tcpTrace那么完整,但是可以很方便的让我们查看到大部分soap消息。当然这只适应svc文件。

 

 

你可能感兴趣的:(response)