为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通信,那么如下操作就是一次“打洞”:
A连接S获取B的公网地址(通过B局域网的NAT对外公布)
A按照这个地址向B随便发一点东西(东西不重要,目的是让对方对你有一定的印象),A的NAT将B地址列入信任列表
毫无疑问,B的NAT把关很严,这种套近乎的方式他见得多了,大部分是图谋不轨,因此他并未理会,也未告知B这个事情。
A告知S他想认识B,希望S帮忙撮合
S当然是B的NAT熟悉的人,这个媒人已经帮B促成千万次的约会了,因此S被准许将A的意图告知B,并给了A的公网地址(通过A的NAT对外公布),B答应考虑A的请求
若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)
一个绑定由若干绑定元素构成,每个绑定元素负责客户端和服务器端的信道管理器ChannelManager的创建,信道管理器在客户端和服务器端有不同的名称,前者为信道工厂ChannelFactory,后者为信道监听器ChannelListener,他俩有个共同的责任就是创建各自对应(即在客户端和服务器端分别创建)的信道。一个信道管理器创建相应类型的信道(由于一般对同一个连接来说,一个类型在所在的信道栈里只有一个的信道,因此我们可以说信道管理器和信道一一对应,有信道栈,即有信道管理器栈)。一个信道有所谓的“信道形状”,表示它是什么类型的信道,即输出、输入、请求、回复还是双工。另外信道从会话角度还分为数据包信道(笔者注:该名词取自《WCF技术剖析》一书,但个人觉得应该是非会话信道更准确,因为数据包和传输信道而非所有种类信道更相关,而任何传输信道传送的都是数据包)和会话信道(此处所谓的会话包括协议本身的会话机制如tcp协议,也包括WCF框架提供的会话机制),很明显,UDP使用的就应该是数据包信道(按前面所述,这句话虽然无错,但也无意义。任何传输信道都可以附加会话机制以实现相关消息的来回传送)。
绑定元素构成绑定的次序也很重要,按上一条所述可得,绑定元素的次序决定了信道的次序,而信道的次序本质上决定了绑定的特性与能力。消息在信道栈中应该是自上而下逐信道处理的。
WCF的终结点三要素中,我们可以只通过绑定和终结点地址进行客户端和服务器端的[消息]通信,服务接口要素只是借助通信的功能调用服务端的方法并返回而已(这句话并不确切,确切地说,服务契约中的操作契约本质上定义了操作(而非信道)采用的消息交换模式,以及消息的格式,这个作用主要在发布元数据生成WSDL时用到。)。
终结点有逻辑地址和物理地址之分,一般说的终结点地址是逻辑地址,我个人理解逻辑地址就是SOAP的To,可以指定物理地址从而忽略逻辑地址,否则WCF会有自己的一套映射机制从逻辑地址得到物理地址。最终的调用地址是物理地址。 假设我们为一个服务(同一个服务接口)指定了3个终结点地址(逻辑地址),其中两个终结点地址分配同一个监听地址(物理地址),此时有两个监听地址。那么当服务被成功寄宿时,WCF会创建两个信道分发器ChannelDispatcher对象,每个信道分发器各拥有属于自己的信道监听器对象,它们分别绑定到两个监听地址进行服务调用请求的监听。此外,WCF还会为3个终结点地址创建3个终结点分发器EndpointDispatcher。当信道分发器通过信道监听器接收到消息时,将会根据消息自身携带的信息按照终结点分发器的指定规则选择与之相匹配的终结点分发器,这一过程称为消息筛选MessageFilter。
操作约束OperationContract指定的Action应该对应的是SOAP的Action,作为上述的筛选规则供信道分发器将消息路由到终结点分发器。
在WCF中有一种服务操作能处理所有的消息类型,叫做非匹配处理器,它接受一个Message类型的参数(因为所有的服务调用最终都转化为Message抵达服务器),返回Message或void,且Action被指定为“*”。对一个服务契约来说,这样的操作契约只能有一个。同理,ReplyAction=”*” 可以使用一个Operation处理所有的返回消息。
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接口。
补充第7条:WSDL元数据扩展(自定义)导入(包括自定义策略导入),是在客户端通过客户端配置文件或Svcutil.exe配置文件或通过编程方式将其添加到System.ServiceModel.Description.WsdlImporter构造函数加载进行的。
下一篇我会参照上面给出的微软的那个示例,在WCF下实现UDP通信,并增加P2P功能。
ps:这篇是从百度空间搬过来的,由于百度喜欢和谐,导致很多超链接丢失,偶尔还有丢失语句的情况。我粗粗查看了一遍,修复了几处。关于丢失的链接,若读者有兴趣则可根据文本谷歌,应该能找到对应的资料。
为WCF增加UDP绑定(储备篇)的更多相关文章
- 我的服装DRP之即时通讯——为WCF增加UDP绑定(应用篇)
发个牢骚,博客园发博文竟然不能写副标题.这篇既为我的服装DRP系列第二篇,也给为WCF增加UDP绑定系列收个尾.原本我打算记录开发过程中遇到的一些问题和个人见解,不过写到一半发现要写的东西实在太多,有 ...
- 为WCF增加UDP绑定(实践篇)
这两天忙着系统其它功能的开发,没顾上写日志.本篇所述皆围绕为WCF增加UDP绑定(储备篇)中讲到的微软示例,该示例我已上传到网盘. 上篇说道,绑定是由若干绑定元素有序组成,为WCF增加UDP绑定其实就 ...
- WCF系统内置绑定列表与系统绑定所支持的功能
WCF系统内置绑定列表 绑定 配置元素 说明 传输协议 编码格式 BasicHttpBinding <basicHttpBnding> 一个绑定,适用于与符合 WS-Basic Pro ...
- WCF 通讯标准绑定
WCF 通讯标准绑定 一.预定义标准绑定 标准绑定 说明 BasicHttpBinding BasicHttpBinding 绑定用于最广泛的互交操作,针对第一代Web服务,所使用的传输协议是HTTP ...
- udp绑定信息
1. udp网络程序-端口问题 会变的端口号 重新运行多次脚本,然后在“网络调试助手”中,看到的现象如下: 说明: 每重新运行一次网络程序,上图中红圈中的数字,不一样的原因在于,这个数字标识这个网络程 ...
- [WCF编程]6.绑定行为
一.绑定行为概述 为了支持服务端的其它本地特性,WCF定义了行为的概念.行为就是服务的本地特性,不会影响服务的通信模式.客户端并不知道服务端行为,所以行为不会出现在服务的绑定和发布的元数据中.说下WC ...
- [WCF编程]5.绑定概述
一.绑定概述 WCF提供了一个编程框架,可以抽象化服务创建的复杂过程.绑定允许开发人员将精力集中在问题本身上,而无需考虑如何创建允许系统运行的架构,因为WCF已经创建了架构. 绑定类型是开发人员控制W ...
- 使用多种客户端消费WCF RestFul服务(四)——Jquery篇
Jquery篇 互联网开发中少不了各类前端开发框架,其中JQUERY就是最流行之一,本篇我们就采用JQUERY来消费WCF RestFul服务,其中用到JSON基础知识,如果有想了解的朋友,请访问:& ...
- TCP、UDP绑定同一端口通信的解释
昨日突然讨论起TCP与UDP是否可以在同一端口进行绑定,通信. 在印象当中我记得是可以的,今日google了相关资料, 确定以及肯定的: TCP.UDP可以绑定同一端口来进行通信: 网络中可以被命名和 ...
随机推荐
- nutch2.2.1+mysql抓取数据
基本环境:linux centos6.5 nutch2.2.1 源码包, mysql 5.5 ,elasticsearch1.1.1, jdk1.7 1.下载地址http://mirror.bjtu. ...
- DLL和OCX注册
在注册DLL或者OCX的方法应该使用regsvr32.exe,使用得多了一定会觉得在cmd运行中写一长串东西很烦人吧!这里向大家介绍一种麻烦一次方便一生的方法.这个方法只要右击你想注册或者反注册的DL ...
- 未知高宽的div在其父级div中垂直居中显示
(一)如果已知子div的高宽 .father { position: relative; } .child { width: 100px; height: 80px; position: absolu ...
- Mybatis 使用Mapper接口的Sql动态代码方式进行CURD和分页查询
1.Maven的pom.xml 2.配置文件 2.1.db.properties 2.2.mybatis.xml 2.3.log4j.xml 3.MybatisUtil工具类 4.Mapper映射文件 ...
- bias、variance与拟合之间的关系
Error = Bias^2 + Variance+Noise 误差的原因: 1.Bias反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度,即算法本身的拟合能力. 2.Variance ...
- php pdo 获取数据转换为json
php 查询语句获取数据,数据库有好多表现形式,如何拿出自己需要的数据 $raceSQL ='select id, race_name,race_code,content from je_race ' ...
- django静态文件的配置
Django static静态配置文件 对于Django来说静态文件一般交由Web服务器处理,Django本身不处理静态文件.为了使Django开发环境能够处理静态文件,Django有和生产环境不 ...
- SQL一些记录
1,2字段约束create unique index [索引名] on 软件信息表(S_SName,S_Edition)
- 前端常用的库和实用技术之JavaScript 模块化
模块化概念 AMD是requirejs在推广过程中对模块化定义的规范化产出. 异步加载模块,依赖前置,提前执行 Define定义模块define(['require','foo'],function( ...
- yum -y install python-devel
yum -y install python-devel的时候报错如图: Could not retrieve mirrorlist http://mirrorlist.centos.org/?rele ...