在WCF中的消息交换模式:
(一)one way
单向:使用单向操作时,只能传输一个消息。 接收方不发送答复消息,发送方也不需要获得答复消息。如果是单向,那么意味着服务处理客户请求的过程中出现的异常信息,也无法传递到客户。
现在演示一个单向交换:
[OperationContract(IsOneWay=true)]
void ChatMessage(string strMsg);
实现:
public void ChatMessage(string strMsg)
{
Console.WriteLine("用户的信息:{0}",strMsg);
}
在客户端调用,并传送字串:12345
这里,通过包的情况可以看出:客户端只有请求消息,但没有响应。在这里有个疑问,虽然是单向,而没有响应,这个响应是指没有soap响应。但还是有http头信息回来。
HTTP/1.1 202 Accepted
Content-Length: 0
Server: Microsoft-HTTPAPI/1.0
Date: Sat, 13 Mar 2010 02:28:10 GMT
如果要设置单向交换,那么在契约上添加IsOneWay=true,因为是单向的,不向客户端返回消息,所以对单向的方法有些限制,做为单向的方法不能有返回值,且不能带有out,ref的参数。
(二)Request/Reply
RR模式是默认的消息交换模式。客户端请求并等待服务端的应答,即使对于无返回值的方法来说,也会返回应答。因为这是默认的消息交换模式,所以只要添加OperationContract即可。
去掉单向中的单向属性:
[OperationContract]
void ChatMessage(string strMsg);
这就是一个RR消息交换模式,现在看它的包情况:
只看请求部分的body部分:
<s:Body>
<ChatMessage xmlns="http://www.selftest.com/test1">
<strMsg>12345</strMsg>
</ChatMessage>
</s:Body>
然后看响应部分:
<s:Envelope
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">
http://www.selftest.com/test1
/ICaculateService/ChatMessageResponse</a:Action>
<a:RelatesTo>
urn:uuid:38af
</a:RelatesTo>
</s:Header>
<s:Body>
<ChatMessageResponse
xmlns="http://www.selftest.com/test1" />
</s:Body>
</s:Envelope>
RR模式比较明确,客户端就是请求,而服务端用于应答。
(三)Duplex
双工消息交换模式,它可以使客户端程序能够侦听入站操作调用。让客户端可以处理从服务端发出的调用。
为服务契约添加回调属性。
[ServiceContract(CallbackContract=typeof(ISelfCallback))]
public interface ICaculateService
回调接口:
[ServiceContract]
public interface ISelfCallback
{
[OperationContract]
void DoService(string strMsg);
}
回调接口用于向客户端发送请求。
现在为ChatMessage
方法添加回调信息:
public void ChatMessage(string strMsg)
{
Console.WriteLine("客户端用户的信息:{0}",strMsg);
ISelfCallback _callback =
OperationContext.Current.GetCallbackChannel<ISelfCallback>();
_callback.DoService("这是服务端的时间:"+ DateTime.Now);
}
客户端实现回调接口:
public class SelfCallBack1 : FirstInstance.ICaculateServiceCallback
{
public void DoService(string strMsg)
{
Console.WriteLine("客户端一方接收到的信息:{0}", strMsg);
}
}
在调用时:
SelfCallBack1 _callback = new SelfCallBack1();
FirstInstance.CaculateServiceClient client =
new UNTest.FirstInstance.CaculateServiceClient
(new InstanceContext(_callback));
client.ChatMessage("12345");
请服务端请求后,得到对方的应答,并处理来自服务端的请求。