WCF之直接通过绑定进行消息通信
关于WCF消息的通信方式,想必有很多人已经知道了,这里呢~我就不在老生长谈了。
WCF采用完全基于消息的通信方式,所有的功能,无论是与业务有关的,还是与业务无关的,都是通过消息交换来实现的。除了最基本的消息编码和传输之外,其他的一些功能也需要通过在消息交换过程中添加一些相应的消息处理操作来实现,典型的呢包括
- 事务流转(Transaction Flowing):将从客户端开始的事务流转到服务端,从而将服务的执行纳入该事物。
- 安全传输(Tranfer Security):保证数据包或消息的安全,避免被恶意篡改与窥视等。
- 可靠传输(Reliab Messaging):网络环境不好的情况下保证数据包或消息的可靠、有序传输。
这些特殊的功能也通过相应的信道来承载。说的专业一点,WCF是遵循WS_*标准的,WS_*通过一系列的协议制定了一套业界普遍遵循的WEB Service标准,使得不同厂商、不同平台之间的互操作成为可能。WCF 对最新的WS_*提供了支持,随着WS_*的逐步完善,WCF也会与之保持同步。绝大部分WS_*协议的支持都是通过在信道栈中添加相应的信道实现的,所以我们把这样的信道称为协议信道。必须的传输信道和消息编码信道,加上可选的协议信道组成了一个更加完整的、功能更加强大的信道栈。
为了让大家对绑定和信道栈之间的关系有一个深入的认识,我写了一个Demo,通过这个小的Demo,相信大家对如何通过绑定创建信道栈,如何通过信道栈进行消息的发送和接收有一个感性的认识。
- 创建请求监听端应用程序 --代码如下:
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 Uri listenUri = new Uri("http://127.0.0.1:9999/listener");
8 Binding binding = new BasicHttpBinding();
9
10 IChannelListener<IReplyChannel> channelListener = binding.BuildChannelListener<IReplyChannel>(listenUri);
11 channelListener.Open();
12 IReplyChannel channel = channelListener.AcceptChannel(TimeSpan.MaxValue);
13 channel.Open();
14
15 Console.WriteLine("开始监听……");
16 while (true)
17 {
18 RequestContext requestContext = channel.ReceiveRequest(TimeSpan.MaxValue);
19 Console.WriteLine("接受到请求消息:\n{0}",requestContext.RequestMessage);
20
21 requestContext.Reply(CreateReplyMessage(binding));
22
23
24 }
25 }
26
27
28 static Message CreateReplyMessage(Binding binding)
29 {
30 string action = "urn: artech.com/reply";
31 string body = "这是一个简单的回复消息!";
32
33 try
34 {
35 return Message.CreateMessage(binding.MessageVersion, action, body);
36 }
37 catch (Exception ex)
38 {
39
40 throw ex;
41 }
42
43 }
44 }
45 }
我们通过代码分析,对代码执行的流程进行简单的介绍:首先BasicHttpBinding对象被创建出来,调用绑定对象的BuildChannelListener<IReplyChannel>方法,创建IChannelListener<IReplyChannel>对象。该方法接收一个URI类型的参数,表示监听地址。调用Open方法开启创建出来的信道监听器对象。
在信道监听器通过绑定对象被成功创建并开启后,通过调用AccetChannel方法创建信道栈进行请求的监听,信道栈通过若干信道有序连接而成,方法最终返回的是位于栈顶的信道对象。
一旦信道栈被成功创建,那么就可以利用它对请求消息进行接收、处理了。在这个Demo中通过一个死循环来处理来自不同客户端的消息请求。请求的接收通过IReplyChannel的ReceiveRequest方法实现。该方法接收一个TimeSpan类型参数,代表该方法从执行开始成功接收请求的时间,由于客户端请求的平率不确定,在这里给它指定了一个最大值。ReceiveRequest并不像我们想象的一样返回一个代表请求消息的message对象,而是返回一个RequestContext对象,并通过该对象将创建的回复消息给请求方。
2.创建消息发送端应用程序 --代码如下:
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 Uri listenUri = new Uri("http://127.0.0.1:9999/listener");
8 Binding binding = new BasicHttpBinding();
9 IChannelFactory<IRequestChannel> channelFactory = binding.BuildChannelFactory<IRequestChannel>();
10
11 channelFactory.Open();
12
13 IRequestChannel channell = channelFactory.CreateChannel(new EndpointAddress(listenUri));
14
15 channell.Open();
16
17 Message replyMessage = channell.Request(CreateRequestMessage(binding));
18
19 Console.WriteLine("接收到回复消息\n{0}",replyMessage);
20
21 Console.Read();
22 }
23
24 static Message CreateRequestMessage(Binding binding)
25 {
26 string ation = "urn:artech.com/request";
27
28 string body = "这是一个简单的请求信息!";
29
30 return Message.CreateMessage(binding.MessageVersion,ation,body);
31 }
32 }
33 }
34
飞 发送端的程序和监听端类似,在监听程序中,通过绑定创建了IChannelListener<IReplyChannel>对象,并调用AcceptChannel方法创建监听信道栈并进行消息的接收与处理。
3.输出结果 如果下图所以
照片一直传不上去,不知道是网不行还是甚原因 改天一定补上
由于监听端在接受到请求消息后,向请求端返回了一个回复消息,这个回复消息将会成功输出到消息请求短