一、利用BasicHttpBinding实现消息通信
WCF基础架构由服务模型层和信道层构成,而绑定是两层直接的纽带。绑定创建了处理消息的信道栈,实现消息的传输和处理。在绑定模型中涉及很多通信对象,信道监听器、信道工厂等,它们处于一个层链表中,层链表的每一层都是一个单链表维护自己的消息处理关系和信道关系。当创建信道监听器时触发了监听器层的链表,一并创建基于不同信道的不同信道管理器,再由这些信道管理器创建各自的信道。
废话少说,上代码,服务端:
class Program { static void Main(string[] args) { BasicHttpBinding bind = new BasicHttpBinding(); IChannelListener<IReplyChannel> listener = bind.BuildChannelListener<IReplyChannel>(new Uri("http://localhost:8866")); listener.Open(); IReplyChannel replyChannel = listener.AcceptChannel(TimeSpan.MaxValue); replyChannel.Open(); while (true) { RequestContext context = replyChannel.ReceiveRequest(TimeSpan.MaxValue); Message msg = context.RequestMessage; Console.WriteLine(msg); context.Reply(CreateMessage(bind)); } } private static Message CreateMessage(Binding bind) { XNamespace ns = "http://www.cnblogs.com/lh218"; XElement body = new XElement(new XElement(ns + "Response", new XElement(ns + "result", 3))); return Message.CreateMessage(bind.MessageVersion, "http://www.cnblogs.com", body); } }
BasicHttpBinding首先创建了一个信道监听器,Open之后创建信道,在while循环中接受客户端的消息。ReceiveRequest方法中传入一个TimeSpan类型参数表示等待时间间隔。网络通信需要时间,倘若等待一定长的时间后没有收到消息可以抛出异常,这个参数就是定义这个时间范围,这里传入最大值表示无限等待。接受到消息后返回的是RequestContext对象,可以通过它获取消息和回复消息。
客户端:
class Program { static void Main(string[] args) { BasicHttpBinding bind = new BasicHttpBinding(); IChannelFactory<IRequestChannel> request = bind.BuildChannelFactory<IRequestChannel>(); request.Open(); IRequestChannel requestChannel=request.CreateChannel(new EndpointAddress("http://localhost:8866")); requestChannel.Open(); Message msg= requestChannel.Request(CreateMessage(bind)); Console.WriteLine(msg); } private static Message CreateMessage(Binding bind) { XNamespace ns = "http://www.cnblogs.com/lh218"; XElement body = new XElement(new XElement(ns + "Request", new XElement(ns + "x", 1), new XElement(ns + "x", 2))); return Message.CreateMessage(bind.MessageVersion, "http://www.cnblogs.com", body); } }
创建信道工厂,Open,在创建信道,Open,创建信道后就可以直接发送消息了。这里定义了一个静态方法CreateMessage用于创建消息,从消息内容上看可以很容易的看出来客户端发送请求想知道1+2等于多少,服务端回复等于3。当然这些消息都是自己创建的,当真正调用一个实现了契约的方法,这些消息的创建都是WCF内部自动完成的。
客户端发送的消息:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addr essing/none">http://localhost:8866/</To> <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/ addressing/none">http://www.cnblogs.com</Action> </s:Header> <s:Body> <Request xmlns="http://www.cnblogs.com/lh218"> <x>1</x> <x>2</x> </Request> </s:Body> </s:Envelope>
服务端回复消息:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<Response xmlns="http://www.cnblogs.com/lh218">
<result>3</result>
</Response>
</s:Body>
</s:Envelope>