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

日前我开发的服装DRP需要用到即时通信方面的技术,比如当下级店铺开出零售单时上级机构能实时收到XX店铺XX时XX分卖出XX款衣服X件之类的信息,当然在上级发货时,店铺里也能收到已经发货的提醒。即时通信技术能运用到DRP系统的很多方面,若深入下去,甚至可以开发一个系统内部的通讯模块,类似于QQ。当前大部分的企业管理系统开发类似功能,使用的都是效率及其低下的定时拉数据的方式,即每隔一段预定时间去数据存储区(一般为数据库)读取数据,然后在代码层判断,若数据同内存数据一致则丢弃,否则更新内存数据并同步更新UI。这种方式的缺点显而易见:效率低;服务器压力大;数据实时性不强。因此我花时间了解了我可能用到的关于真正意义上的即时通信技术的一些知识,作为开发之前的知识储备。有关这个功能的开发我会详细记录日志供其他朋友和自己以后参考学习。

  • P2P传输协议选择:

一般集中在TCP和UDP上,这两种各有优劣,说简单点就是TCP安全稳健效率低,而UDP效率高但可能会丢三落四(视网络情况定,丢包的概率不高)。说些题外话,有时写代码写着写着就会想到哲学方面的东西,比如TCP和UDP的比较会发现,效率高且安全可靠的传输协议并不存在,这种情况屡见不鲜,所谓鱼和熊掌不可兼得,也许这就是宇宙的法则吧。我选择UDP,首先UDP丢包的概率不高,其次若选择TCP还要考虑连接数啥啥的问题,不胜烦恼。

  • “打洞”

这个词让人浮想联翩,对搞网络通信的人来说却毫无吸引力。这种体力活源自IP地址太少,各种NAT设备(俗称路由器)应运而生,解决了僧多粥少的问题,但引入了另一个问题,即任意连网的电脑并不能确保可以直接通信,假如它们隐藏在各自的NAT之后,并没有确切的网络地址,地址都不知道,谈何通信。虽然隐藏在NAT后面电脑没有公网地址,但NAT知道哪些消息是发给谁并知道怎么把这些消息送达,前提是这个消息是受信任的。

“打洞”(我不知道为什么要叫这个名词)简单的说就是在两端NAT建立起信任的连接。这个过程首先需要一台拥有公网地址的机器S作为媒介,现在假设处于某个局域网内部的机器A想同另一个局域网内的机器B通信,那么如下操作就是一次“打洞”:

  1. A连接S获取B的公网地址(通过B局域网的NAT对外公布)
  2. A按照这个地址向B随便发一点东西(东西不重要,目的是让对方对你有一定的印象),A的NAT将B地址列入信任列表
  3. 毫无疑问,B的NAT把关很严,这种套近乎的方式他见得多了,大部分是图谋不轨,因此他并未理会,也未告知B这个事情。
  4. A告知S他想认识B,希望S帮忙撮合
  5. S当然是B的NAT熟悉的人,这个媒人已经帮B促成千万次的约会了,因此S被准许将A的意图告知B,并给了A的公网地址(通过A的NAT对外公布),B答应考虑A的请求
  6. 若B对A有意,那么她可以按照A的地址随便发一点东西过去,此时B的NAT将A地址列入信任列表。此时“打洞”完毕。

少年们于是不淡定了,啥都没有发生呢,怎么就完了呢。其实“打洞”过程就是相互建立信任的过程,相互加入各自的信任列表之后,以后就能按照各自NAT的公网地址进行直连通信了,这又是另外的故事了。上述过程对少数NAT设备来说可能并不准确。

UDP组播通信似乎用不着“打洞”(假如路由器支持IGMP协议的话),不知道我的这个理解有没有问题,待以后验证。

  • 为WCF增加UDP绑定

我的服装DRP采用WCF作为服务提供者。本来我想绕过WCF,直接操作Socket来进行UDP通信。后来想说顺便熟悉下WCF这个框架的底层机制,于是下载了微软的一个示例,并研读了蒋大牛的《WCF技术剖析》,这本书写的非常好。两者结合,许多困惑之处往往能柳暗花明。现将这两天的学习做一总结。(听说WCF4.5加入了UDP绑定,具体看What’s new in WCF 4.5? UDP transport support

  1. 一个绑定由若干绑定元素构成,每个绑定元素负责客户端和服务器端的信道管理器ChannelManager的创建,信道管理器在客户端和服务器端有不同的名称,前者为信道工厂ChannelFactory,后者为信道监听器ChannelListener,他俩有个共同的责任就是创建各自对应(即在客户端和服务器端分别创建)的信道。一个信道管理器创建相应类型的信道(由于一般对同一个连接来说,一个类型在所在的信道栈里只有一个的信道,因此我们可以说信道管理器和信道一一对应,有信道栈,即有信道管理器栈)。一个信道有所谓的“信道形状”,表示它是什么类型的信道,即输出、输入、请求、回复还是双工。另外信道从会话角度还分为数据包信道(笔者注:该名词取自《WCF技术剖析》一书,但个人觉得应该是非会话信道更准确,因为数据包和传输信道而非所有种类信道更相关,而任何传输信道传送的都是数据包)和会话信道(此处所谓的会话包括协议本身的会话机制如tcp协议,也包括WCF框架提供的会话机制),很明显,UDP使用的就应该是数据包信道(按前面所述,这句话虽然无错,但也无意义。任何传输信道都可以附加会话机制以实现相关消息的来回传送)。
  2. 绑定元素构成绑定的次序也很重要,按上一条所述可得,绑定元素的次序决定了信道的次序,而信道的次序本质上决定了绑定的特性与能力。消息在信道栈中应该是自上而下逐信道处理的。
  3. WCF的终结点三要素中,我们可以只通过绑定和终结点地址进行客户端和服务器端的[消息]通信,服务接口要素只是借助通信的功能调用服务端的方法并返回而已(这句话并不确切,确切地说,服务契约中的操作契约本质上定义了操作(而非信道)采用的消息交换模式,以及消息的格式,这个作用主要在发布元数据生成WSDL时用到。)。
  4. 终结点有逻辑地址和物理地址之分,一般说的终结点地址是逻辑地址,我个人理解逻辑地址就是SOAP的To,可以指定物理地址从而忽略逻辑地址,否则WCF会有自己的一套映射机制从逻辑地址得到物理地址。最终的调用地址是物理地址。 假设我们为一个服务(同一个服务接口)指定了3个终结点地址(逻辑地址),其中两个终结点地址分配同一个监听地址(物理地址),此时有两个监听地址。那么当服务被成功寄宿时,WCF会创建两个信道分发器ChannelDispatcher对象,每个信道分发器各拥有属于自己的信道监听器对象,它们分别绑定到两个监听地址进行服务调用请求的监听。此外,WCF还会为3个终结点地址创建3个终结点分发器EndpointDispatcher。当信道分发器通过信道监听器接收到消息时,将会根据消息自身携带的信息按照终结点分发器的指定规则选择与之相匹配的终结点分发器,这一过程称为消息筛选MessageFilter。
  5. 操作约束OperationContract指定的Action应该对应的是SOAP的Action,作为上述的筛选规则供信道分发器将消息路由到终结点分发器。
  6. 在WCF中有一种服务操作能处理所有的消息类型,叫做非匹配处理器,它接受一个Message类型的参数(因为所有的服务调用最终都转化为Message抵达服务器),返回Message或void,且Action被指定为“*”。对一个服务契约来说,这样的操作契约只能有一个。同理,ReplyAction=”*” 可以使用一个Operation处理所有的返回消息。
  7. WCF终结点信息最终要被转化为WSDL方才能被客户端理解调用,这涉及到WsdlExporter这个类,具体可看WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]。为了让我们自定义的绑定元素被WsdlExporter导出为对应的WSDL元素,我们需要让自定义绑定元素实现WSDL导出扩展(WSDL Export Extension)和策略导出扩展(Policy Export Extension)。关于策略一说可阅读Understanding Web Services Policy。简单地说,策略描述的是服务的能力和要求(目前我只看到要求),假如没有导出相关策略,客户端就不知道这一部分的具体要求,可能会导致请求得不到服务的正确响应。因此,策略导出是自定义绑定的一个职责。策略属于WSDL的一部分。关于策略导出请参看Extending WSDL and Policy, Part 1. Exporting custom policy assertions。有导出就有导入,导入是在客户端进行的。对于自定义策略来说,我们要实现IPolicyImportExtension接口,以便获取导出的策略并将其按照预期应用到绑定或其它地方,具体步骤请参看IPolicyImportExtension接口
  8. 补充第7条:WSDL元数据扩展(自定义)导入(包括自定义策略导入),是在客户端通过客户端配置文件或Svcutil.exe配置文件或通过编程方式将其添加到System.ServiceModel.Description.WsdlImporter构造函数加载进行的。

下一篇我会参照上面给出的微软的那个示例,在WCF下实现UDP通信,并增加P2P功能。

ps:这篇是从百度空间搬过来的,由于百度喜欢和谐,导致很多超链接丢失,偶尔还有丢失语句的情况。我粗粗查看了一遍,修复了几处。关于丢失的链接,若读者有兴趣则可根据文本谷歌,应该能找到对应的资料。

时间: 2024-08-03 17:10:20

为WCF增加UDP绑定(储备篇)的相关文章

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

这两天忙着系统其它功能的开发,没顾上写日志.本篇所述皆围绕为WCF增加UDP绑定(储备篇)中讲到的微软示例,该示例我已上传到网盘. 上篇说道,绑定是由若干绑定元素有序组成,为WCF增加UDP绑定其实就是为绑定增加UDP传输绑定元素,最终目的是在信道栈中生成UDP传输信道.因此我们定义一个类UdpTransportBindingElement,它继承自TransportBindingElement表明这是传输相关的绑定元素.示例中该类还实现了IPolicyExportExtension和IWsdl

程序猿二三事之Java基础--Java SE 5增加的特性--语法篇(一)

程序猿二三事之Java基础–Java SE 5增加的特性–语法篇(一) [ TOC ] 为什么是Java SE 5? 目前已经到了JDK-8u74了,JDK7的主版本已经于2015年4月停止公开更新. 那为什么还要来说Java/JDK5呢? Java SE在1.4(2002)趋于成熟,随着越来越多应用于开发企业应用,许多框架诞生于这个时期或走向成熟. Java SE 5.0的发布(2004)在语法层面增加了很多特性,让开发更高效,代码更整洁. 自动装箱/拆箱.泛型.注解.for循环增强.枚举.可

WCF 通讯标准绑定

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

WCF学习之旅----正式篇之基础框架

服务类包括服务契约IWCFService.操作契约OperationContract.和数据契约DataContract. using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.ServiceModel.Description; using System.Runtime.Serialization;

[WCF编程]6.绑定行为

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

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

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

SpringMVC学习10-参数绑定高级篇

1.包装类型pojo参数绑定 需求 商品查询controller方法中实现商品查询条件传入. 实现方法 第一种方法:在形参添加HttpServletRequest request参数,通过request接收查询条件参数. 第二种方法:在形参中让包装类型的pojo接收查询条件参数. 分析: 页面传参数的特点:复杂,多样性.条件包括 :用户账号.商品编号.订单信息... 如果将用户账号.商品编号.订单信息等放在简单pojo(属性是简单类型)中,pojo类属性比较多,比较乱. 建议使用包装类型的poj

爬虫知识储备篇---分析http请求

(1).为何需要进行HTTP请求分析 答:方便我们编写的爬虫精准定位爬取目标 (2).知识储备 1.什么是抓包? 抓包:抓取客户端与服务器之间进行通信时产生的数据包 2.了解抓包工具:chrome下的开发者模式,使用F12即可打开 功能结构分析:(参考文档:http://www.css88.com/doc/chrome-devtools/) Elements(元素面板):用于查看网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能在浏览器中得到实时反馈 Console(控制台面板):

OC学习之知识储备篇

1. Objective-C是基于C语言的. a. 在C语言的基础之上新增了面向对象的语法. b. 将C语言中复杂的.繁琐的语法封装的更为简单. 2. Objective-C程序的源文件的后缀名.m  message  消息机制. C程序的源文件的后缀名是.c 3. main函数仍然是Objective-C程序的入口和出口. main函数的参数可以有 也可以没有. 参数的功能: 在终端单独运行程序的时候 可以让用户直接传入一些数据进来. 返回值: 代表程序结束的状态. 0代表正常结束. 非0代表