为WCF增加UDP绑定(实践篇)

这两天忙着系统其它功能的开发,没顾上写日志。本篇所述皆围绕为WCF增加UDP绑定(储备篇)中讲到的微软示例,该示例我已上传到网盘。

上篇说道,绑定是由若干绑定元素有序组成,为WCF增加UDP绑定其实就是为绑定增加UDP传输绑定元素,最终目的是在信道栈中生成UDP传输信道。因此我们定义一个类UdpTransportBindingElement,它继承自TransportBindingElement表明这是传输相关的绑定元素。示例中该类还实现了IPolicyExportExtension和IWsdlExportExtension接口,关于这两个接口,我知道它们的作用,但看到代码却是一头雾水,我认为要能理解这块内容首先要对WSDL相关的各种规范做一详细了解,目前我先不考虑。对这有兴趣的朋友可阅读蒋大牛的元数据架构体系全景展现。以前总觉得WCF不外如是,不成想这水也太特码深了(WCF相关的概念有很多,包括ChannelDispatcher、ListenerHandler、ChannelHandler等,这些和消息传输关系不大)。

UdpTransportBindingElement主要负责绑定管理类的创建工作,服务器端和客户端分别创建的是UdpChannelListener和UdpChannelFactory。UdpChannelFactory的实现比较简单,我们重点看UdpChannelListener实现。网上资料都有类似这么一段描述:ChannelListener负责监听消息,一旦消息抵达则使用对应的Channel接收消息。在UDP解决方案中,消息监听依赖System.Net.Sockets.Socket类,示例中调用该类的BeginReceiveFrom方法进行异步监听。

 1 void StartReceiving(object state) 2 { 3     Socket listenSocket = (Socket)state; 4     IAsyncResult result = null; 5  6     try 7     { 8         lock (ThisLock) 9         {10             if (base.State == CommunicationState.Opened)11             {12                 EndPoint dummy = CreateDummyEndPoint(listenSocket);13                 byte[] buffer = this.bufferManager.TakeBuffer(maxMessageSize);14                 result = listenSocket.BeginReceiveFrom(buffer, 0, buffer.Length,15                     SocketFlags.None, ref dummy, this.onReceive, new SocketReceiveState(listenSocket, buffer));16             }17         }18 19         if (result != null && result.CompletedSynchronously)20         {21             ContinueReceiving(result, listenSocket);22         }23     }24     catch (Exception e)25     {26         Debug.WriteLine("Error in receiving from the socket.");27         Debug.WriteLine(e.ToString());28     }29 }

需要关注Socket.BeginReceiveFrom方法,MSDN有一段描述:当应用程序调用 BeginReceiveFrom 时,系统将会使用单独的线程来执行指定的回调方法,并将在 EndReceiveFrom 上一直阻塞到 Socket 读取数据或引发异常为止。但示例中有判断该方法是否同步执行的代码,因此我认为该方法并不会每次都用异步的方式来进行数据的接收,具体请看我的另一篇文章关于IAsyncResult接口的CompletedSynchronously属性。

不出意外,当数据抵达后采用Socket.EndReceiveFrom获取。我看到这里的时候觉得有点不对劲,不是说“ChannelListener负责监听消息,一旦消息抵达则使用对应的Channel接收消息”吗?既然ChannelListener都把数据接收完成了,还要Channel何用。此处似乎Channel真的只是走个过场,它存在的意义只是因为WCF框架需要它。所以我们还是需要将已接收的消息从ChannelListener传递给Channel,于是我翻看代码,希望找到一个event,在消息接收完毕后触发,以便Channel能实时得到消息可用的信号,结果没找到哪怕一个event的声明,于是我苦恼了。

 1 public interface IInputChannel : IChannel, ICommunicationObject 2 { 3     EndpointAddress LocalAddress { get; } 4  5     IAsyncResult BeginReceive(AsyncCallback callback, object state); 6     IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state); 7     IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state); 8     IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state); 9     Message EndReceive(IAsyncResult result);10     bool EndTryReceive(IAsyncResult result, out Message message);11     bool EndWaitForMessage(IAsyncResult result);12     Message Receive();13     Message Receive(TimeSpan timeout);14     bool TryReceive(TimeSpan timeout, out Message message);15     bool WaitForMessage(TimeSpan timeout);16 }

从IInputChannel的定义可以看到,什么时候接收消息,什么时候等待,是不可控的,因为这些方法可以外部调用(一般是WCF框架自己调用)。简单地说,就是IInputChannel本身获取消息采用的是拉模式,而非推模式。为什么WCF框架不使用event模式(推模式)呢,我没有深入研究过,有知道的朋友还望赐教。这些方法调用时间不知,但若有可用消息时,不论何时调用Receive方法,我们都应该返回正确的Message,换句话说,从消息抵达到获取消息,可能有个时间差,这段时间内,消息数据不能丢失,于是我们应该有个临时存储消息数据的地方。考虑到消息数量和处理顺序,先入先出队列是个不错的选择。不出所料,示例中有个InputQueue类,该类相当复杂,不过万变不离其宗,UdpChannelListener将接收到的消息存入InputQueue,UdpInputChannel从InuptQueue中Receive消息。弄清楚这个,我便释然了。

上述模式只是实现消息从ChannelListener到Channel传递的其中一种方式,只要按规范实现WCF框架提供的关键接口,我们可以使用能想到的任何方式,比如使用event将消息接收工作转移到Channel类(更符合WCF对Channel的职责说明),当然接收到的消息仍旧需要用Receive方法去某个地方读取,因此消息的临时存储仍然必不可少。

由于最近比较忙,就先写到这里吧。示例中最核心的就是ChannelListener、InputQueue和AsyncResult类,AsyncResult类的作用也在关于IAsyncResult接口的CompletedSynchronously属性中有过阐述。若是全面铺开就太多了,有兴趣的朋友可以下载代码自己研究,有什么心得体会欢迎一起讨论。

转载请注明本文出处:http://www.cnblogs.com/newton/archive/2012/11/29/2793931.html

时间: 2024-10-09 01:34:10

为WCF增加UDP绑定(实践篇)的相关文章

为WCF增加UDP绑定(储备篇)

日前我开发的服装DRP需要用到即时通信方面的技术,比如当下级店铺开出零售单时上级机构能实时收到XX店铺XX时XX分卖出XX款衣服X件之类的信息,当然在上级发货时,店铺里也能收到已经发货的提醒.即时通信技术能运用到DRP系统的很多方面,若深入下去,甚至可以开发一个系统内部的通讯模块,类似于QQ.当前大部分的企业管理系统开发类似功能,使用的都是效率及其低下的定时拉数据的方式,即每隔一段预定时间去数据存储区(一般为数据库)读取数据,然后在代码层判断,若数据同内存数据一致则丢弃,否则更新内存数据并同步更

WCF 通讯标准绑定

WCF 通讯标准绑定 一.预定义标准绑定 标准绑定 说明 BasicHttpBinding BasicHttpBinding 绑定用于最广泛的互交操作,针对第一代Web服务,所使用的传输协议是HTTP或者HTTPS,其安全性由传输协议保证. WSHttpBinding WSHttpBinding绑定用于下一代Web服务,它们用SOAP拓展确保安全性,可靠性和事物处理;所使用的传输协议是HTTP或者HTTPS;为了确保安全,实现了WS-Security规范;使用WS-Coordination.WS

[WCF编程]6.绑定行为

一.绑定行为概述 为了支持服务端的其它本地特性,WCF定义了行为的概念.行为就是服务的本地特性,不会影响服务的通信模式.客户端并不知道服务端行为,所以行为不会出现在服务的绑定和发布的元数据中.说下WCF下“契约(Contract)”和“行为(Behavior)”的区别:契约是涉及双边的描述(契约是服务的提供者和服务消费者进行交互的手段),那么行为就是基于单边的描述.客户端行为体现的是WCF如何进行服务调用的方式,而服务端行为则体现了WCF的请求分发方式.所以服务契约会通过元数据对外发布,而WCF

WCF 之 通过绑定进行消息通信

        WCF可以分成两个部分:服务模型层(Service Model Layer)和信道层(Channel Layer).服务模型层建立在信道层之上,提供了一个统一的.可扩展的编程模型.信道层则通过绑定创建的信道栈为消息通信提供了一个传输.处理的通道. 绑定与信道栈(Binding and Channel Stack) 绑定,在WCF整个结构体系中扮演着中间人的角色.当服务被成功寄宿时,WCF通过终结点的绑定对象创建一个或多个信道监听器(ChannelListener),绑定到监听端口

WCF 内置绑定在不同的传输安全模式下的信道层

basicHttpBinding Transport安全模式信道层 Message安全模式信道层 TransportWithMessageCredential安全模式信道层 TransportCredentialOnly安全模式信道层 webHttpBinding Transport安全模式信道层 TransportCredentialOnly安全模式信道层 wsHttpBinding/ws2007HttpBinding Message安全模式信道层 Transport安全模式信道层 Trans

Easyradius 1.699更新,增加用户设备绑定、桥接用户管理功能

最近几天,由于IDC机房设备的问题,导致OA连接3天一天挂2次,真是把我抑闷着,最事一个烦事特别多 好不容易等了一个五一假期,也不得空,把最近一些网友反馈的OA的一些功能及BUG进行修复,主要是以下几个大问题 1.增加同步备注信息到路由的选项2.增加用户到期后,是否可以使用其他套餐充值卡充值3.增加用户线路绑定功能,即用户VLANID绑定在机柜4.增加WayOs PPPoE桥接的用户管理5.增加用户中心二维码生成功能6.增加用户到期时间段10:00和18:007.增加登陆系统时,自动弹出系统信息

WCF基础:绑定(三)

在WCF绑定体系中,绑定创建绑定元素,绑定元素创建绑定监听器/绑定工厂,绑定监听器/绑定工厂创建信道. WCF中绑定是有多个信道相连组成的信道栈,在这个信道栈中必须包含传输信道和编码信道,而且传输信道必须在栈底,在信道栈里面可以添加自定义的信道或是一些协议信道(WS-*标准),在这些协议信道中可以一些消息的处理,比如事务的流转,保证消息的安全传输等.在WCF的信道栈中每一个信道都对信道有这单一的处理功能,多个信道组成的信道栈就可以处理多种功能的消息; Binding public abstrac

WCF绑定netTcpBinding寄宿到IIS

继续沿用上一篇随笔中WCF服务类库 Wettery.WcfContract.Services WCF绑定netTcpBinding寄宿到控制台应用程序 服务端 添加WCF服务应用程序 Wettery.WcfIISHost.Services,其中添加两个WCF服务,GameService.svc  PlayerService.svc,删掉契约接口和 .cs内嵌文件,只留下.svc文件 我们通过Autofac注入契约/服务的依赖关系,Nuget引用 Install-Package Autofac.W

WCF绑定类型选择

WCF绑定类型选择   发布日期:2010年12月10日星期五 作者:EricHu   在开发WCF程序时,如何选择一个适合的绑定对于消息传输的可靠性,传输模式是否跨进程.主机.网络,传输模式的支持.安全性.性能等方面有着重要的影响.而从本质上来看,绑定具有的这些特性源于其使用的网络协议和编码器.绑定是一个定制好的通道栈,包含了协议通道.传输通道和编码器.我们在开发WCF程序时,选择合适定是一个复杂的过程,没有万能的挑选公式可以套用.但是通常地,可以从是否需要交互特性.是否跨主机.是否需要脱机交