1.通道模型概述:
通道栈:WCF为消息的发送和接收简历的消息管道。 通道栈的每个组件都有机会对消息进行处理,整个通道栈可编辑、可插入。确保了灵活性。
通道模型和上层才行隔离完全隔离,任何一个服务和客户端都可配置到不同的通道模型上。通道模型可分上下二部分:上面的成为协议通道,下面的成为传输通道。一个通道栈可有多个下一通道,但一般只有一个传输通道,传输通道负责吧消息进行编码并发送到远端,编码时传输通道需要使用通道栈的编码器如下图:
一般情况,协议通道负责为何消息的非业务逻辑功能,包括事务、日子、可靠消息和安全性等、
在一个通道中必须包含至少一个传输通道和编码器,传输通道负责消息的编码和发送。具体的,传输通道会尝试懂BindingContext对象中查找比编码器。
如果找不到则使用默认的编码器。不同的传输通道将使用不同的传输协议如:HTTP、TCP、IPC等。
2.消息交换模式和通道形状
消息传输层面:6种消息交互模式:
第一、数据报模式
第二、请求-响应模式
第三、双工模式
第四、会话数据报模式
第五、会话请求-响应模式
第六、会话双工模式
一个通道可以支持一种或者几种交互模式,通道通过通道形状(channel shape)来实现具体的交互模式。
通道形状值得是定义了发送、接受消息动作的10个接口,他们均继承自IChannel接口。
这10个接口分别是:IInputChannel、IOutputChannel、IRequestChannel、IreplyChannel、IDuplexChannel、IInputSessionChannel、IOutputSessionChannel、IRequestSessionChannel、IReplySessionChannel、IDuplexSessionChannel.
3、数据报模式:发送端负责把消息发送给对方并且收到确认消息后就完成消息交互的模式。
此模式下发送方唯一能确定的是消息发送成功。对应消息是否最终到达终结点、是否被成功除了、返回结果如何都不知道。示意图:
发送端代码示例:
public class Output { static void Main(string[] args) { //建立自定义通道栈 BindingElement[] bindingElements = new BindingElement[3]; bindingElements[0] = new TextMessageEncodingBindingElement();//文本编码 // bindingElements[1] = new OneWayBindingElement();//OneWayBindingElement可使得传输通道支持数据报模式 bindingElements[3] = new HttpTransportBindingElement();//Http传输 CustomBinding binding = new CustomBinding(bindingElements); //创建消息 using (Message message=new Message.CreateMessage(binding.MessageVersion,"sendMessage","Message Body")) { //创建ChannelFactory IChannelFactory<IOutputChannel> factory = binding.BuildChannelFactory<IOutputChannel>(new BindingParameterCollection()); //打开ChannelFactory factory.Open(); //创建IOutputChannel IOutputChannel outputChannel = factory.CreateChannel(new EndpointAddress("http://localhost:9090.InputService")); //打开IOutputChannel outputChannel.Open(); //发送信息 outputChannel.Send(message); Console.WriteLine("已成功发送信息"); //关闭IOutputChannel outputChannel.Close(); //关闭ChannelFactory factory.Close(); } } }
接收端代码示例:
public class Input { static void Main(string[] args) { //建立和发送端相同的通道栈 BindingElement[] bindingElements = new BindingElement[3]; bindingElements[0] = new TextMessageEncodingBindingElement();//文本编码 //bindingElements[1] = new OneWayBindingElement();//OneWayBindingElement可使得传输通道支持数据报模式 bindingElements[2] = new HttpTransportBindingElement();//Http传输 //创建自定义绑定 CustomBinding binding = new CustomBinding(bindingElements); //建立ChannelListner IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(new Uri("http://localhost:9090/InputService"),new BindingParameterCollection()); listener.Open();//打开ChannelListner //创建IInputChannel IInputChannel inputChannel = listener.AcceptChannel(); inputChannel.Open();//打开IInputChannel Console.WriteLine("开始接收信息"); Message message = inputChannel.Receive();//接收并打印信息 Console.WriteLine("接收到一条消息,action为:{0},body为{1}",message.Headers.Action,message.GetBody<string>()); message.Close();//关闭消息 inputChannel.Close();//关闭通道 listener.Close();//关闭监听器 Console.Read(); } }
4.请求-响应模式:客户端发送一个消息并且接受返回消息完成一次交互。特殊的双工模式。该模式消息必须是客户端发起,并且从服务器端返回的只有一条消息,客户端在发送出消息后会阻止当前线程并且等待服务端返回消息,很适用于HTTP协议。如图交互模式:
为实现请求-响应模式,客户端需要实现IRequestChannel接口,服务端需要实现IReplyChannel接口,代码示例:
发送端:
public class Output { static void Main(string[] args) { BindingElement[] bindingElements = new BindingElement[2]; bindingElements[0] = new TextMessageEncodingBindingElement();//文本编码 bindingElements[1] = new HttpTransportBindingElement();//Http传输 //自定义绑定 CustomBinding binding = new CustomBinding(bindingElements); using (Message message= Message.CreateMessage(binding.MessageVersion,"sendMessage","Message Body")) { //创建ChannelFactory IChannelFactory<IRequestChannel> factory = binding.BuildChannelFactory<IRequestChannel>(new BindingParameterCollection()); factory.Open();//打开ChannelFactory //创建IRequestChannnel IRequestChannel requestChannel = factory.CreateChannel(new EndpointAddress("http://localhost:9090/RequestReplayService")); requestChannel.Open();//打开通道 Message response = requestChannel.Request(message); //发送消息 Console.WriteLine("已成功发送消息"); //查看返回的消息 Console.WriteLine("接收到一套返回消息,action为:{0},body为:{1}",response.Headers.Action,response.GetBody<string>()); requestChannel.Close();//关闭通道 factory.Close();//关闭工厂 } } }
接收端:
public class Input { static void Main(string[] args) { //建立和发送端相同的通道栈 BindingElement[] bindingElements = new BindingElement[2]; bindingElements[0] =new TextMessageEncodingBindingElement();//文本编码 bindingElements[1] = new HttpTransportBindingElement();//Http传输 //自定义绑定 CustomBinding binding = new CustomBinding(bindingElements); //建立ChannelListner IChannelListener<IReplyChannel> listener = binding.BuildChannelListener<IReplyChannel>(new Uri("http://localhost:9090/RequestReplyService"),new BindingParameterCollection()); listener.Open();//打开监听 //创建IReplyChannel IReplyChannel replyChannel = listener.AcceptChannel(); replyChannel.Open();//打开通道 Console.WriteLine("开始接收消息。。。。"); RequestContext requestContext = replyChannel.ReceiveRequest(); Console.WriteLine("接收到一条消息,action为:{0},body为:{1}", requestContext.RequestMessage.Headers.Action, requestContext.RequestMessage.GetBody<string>()); //创建返回消息 Message response = Message.CreateMessage(binding.MessageVersion,"response","response body"); //发送返回消息 requestContext.Reply(response); requestContext.Close(); replyChannel.Close();//关闭通道 listener.Close();//关闭监听 } }
5、双工模式:
原文:https://www.cnblogs.com/professional-NET/p/12637314.html