没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
11页
2006年已经来临,回首刚走过的2005,心中感慨万千。在人生和生活的目标上,有了清晰明确的定位,终于知道了自己喜欢什么样的生活,喜欢什么样的生活方式;在技术上,成熟了不少,眼界也开阔的不少,从面向对象到组件、从.Net到J2EE、从微软到开源,颇有收获。特别值得一提的是,认识了Rod Johnson这个大牛人,也终于在自己的项目中正式使用Spring.net框架来开发了,这确实是一个优秀的框架。而在已经到来的2006年,我有一个主要目标就是B/S应用开发,来填补自己在企业级开发上的另一半空白。 以前就很想将自己在Tcp通信层的开发心得、经验共享出来,但一直没有实现,究其原因,还是自己太懒了。今天终于找到一个时机,写下这篇文章,也算是对2005年的另一种形式的回忆吧。 绝大多数C/S(包括多层)结构的系统中,终端与服务器的通信都是通过Tcp进行的(使用Udp的也有一些,但是其相对于Tcp简单许多,所以不在这里的讨论之列)
资源推荐
资源详情
资源评论
年已经来临,回首刚走过的 ,心中感慨万千。在人生和生活的目标上,有了
清晰明确的定位,终于知道了自己喜欢什么样的生活,喜欢什么样的生活方式;在技术上,成
熟了不少,眼界也开阔的不少,从面向对象到组件、从 到 、从微软到开源,颇有收
获。特别值得一提的是,认识了 这个大牛人,也终于在自己的项目中正式使用
框架来开发了,这确实是一个优秀的框架。而在已经到来的 年,我有一个主
要目标就是 应用开发,来填补自己在企业级开发上的另一半空白。rrrrr
以前就很想将自己在 通信层的开发心得、经验共享出来,但一直没有实现,究其原因,
还是自己太懒了。今天终于找到一个时机,写下这篇文章,也算是对 年的另一种形式的
回忆吧。
绝大多数 (包括多层)结构的系统中,终端与服务器的通信都是通过 进行的(使用
的也有一些,但是其相对于 简单许多,所以不在这里的讨论之列)。通常,这样的
系统都需要处理极大的并发,也就是说随时都可能有成千上万个用户在线,并且每分钟都
可能有数以百计的用户上线下线。由于每个用户都与服务器存在着一个 连接,如何管理所
有这些连接,并使我们的 通信层稳定高效地工作,是我开发的这个“ 通信层”设计
实现的主要目标。
自从 年 月开始至今,我就一直负责某 系统的服务器端的架构设计,并负责整个
通信层的实现,在探索的过程中,逐渐形成了一套可复用的“ 通信层框架”(“框架”这个词真
的蛮吓人,呵呵),其位于 ! 类库的
!"# 命名空间中。现将我在通信层这一块的设计开发经验记录
于此,以便日后回顾。也期大家多多赐教。
我期望的“ 通信层”并不只是能接受连接、管理连接、转发用户请求这么简单,为了构建
一个高度可复用的、灵活的、可接插的 通信层,需要定义很多的规则、接口、契约,这需
要做很多的工作。“ 通信层”决不仅仅只是 协议通信,由于通信与消息联系紧密,不可
避免的需要将“通信的消息”纳入到我们的分析中来,比如,基于 传输的特性,我们可能需
要对接收到的消息进行分裂、重组等(后文中会解释为什么、以及如何做)。请允许我在这里
澄清一下,如果只是解决“仅仅”的 通信问题,我只需要介绍 Tcp 组件就可以了,但是如果
要解决“整个 通信层”的问题,并使之可高度复用,那就需要介绍很多额外的东西,比如,
上面提到的“消息”,以及“消息”所涉及的通信协议。
在我们应用的通信层中,存在以 组件为核心的多个组件,这些组件相互协作,以构建
实现高度可复用的 通信层。这些组件之间的关系简单图示如下:
我先解释一下上图。当网络()组件从某个 连接上接收到一个请求时,会
将请求转发给消息分派器,消息分派器通过 $%!!!&'( 组件获取请求消息的类
型,然后根据此类型要求处理器工厂创建对应类型的请求处理器,请求处理器处理请求并
返回结果。接下来再由网络组件把结果返回给终端用户。在消息分派器进行请求消息分派
之前,可能涉及一系列的操作,像消息加密解密、消息分裂重组、消息验证等。而且,
根据不同的应用,可能有其它的消息转换要求,而且这些操作可能是多样化的,为了满足
这种多样性和可接插性,这就需要消息分派器提供一个插入点,让我们可以随心所欲地插
入自定义的对请求回复消息的预处理和后处理。
上图中消息分派器中可接插的操作除了消息分裂器(使用实线框)是必须的,消息加密
器和消息验证器(使用虚线框)是可选的,应根据你应用的实际情况加以决定是否使用。
关于这几个典型的可接插的组件的功能作用会在后文中介绍。在继续介绍 组件的实现
之前,有必要先提一下 $%!!!&'( 接口的作用,$%!!!&'( 接口用
于抽象我们实际的通信协议,并能从任何一请求回复消息中提取关于本条消息的元数据,
比如,消息的长度、类型等信息。具体的应用必须根据自己的消息协议来实现
$%!!!&'( 接口。关于该接口的定义也在后文中给出。
关于上图,需要提醒的是,整个消息的流动是由 组件驱动的!这篇文章以 组
件和消息分派器组件为索引来组织整个可复用的 通信层的实现。首先,我们来深入到
组件的具体实现中去。r
一.Tcp 组件
). 组件的主要职责
组件的主要职责并不是在一个很短的时间内总结出来的,它是逐步完善的(至今
可能还不够全面)。为了使 组件具有高度的可复用性,需要考虑很多的需求,而所有
这些需求中具有共性的、占主导位置的需求就被纳入到 组件的职责中来了。这个职责
的集合如下:
())rrrrrrr管理所有的 连接以及连接对应的上下文(*)。
()rrrrrrr当某用户上线或下线时,能发出事件通知。
(+)rrrrrrr当在线用户(连接)的数量发生变化时,能发出事件通知。
()rrrrrrr当用户的请求得到回复时,发出事件通知。这一点对于记录用户请求和跟踪用
户请求非常有用)
()rrrrrrr能及时主动关闭指定连接。比如,当某一非法用户登录后,用户验证组件通知
组件强行关闭该用户对应的连接。
()rrrrrrr除了能转发用户请求及对请求的应答(通过消息分派器)外,还能直接对指定
的用户发送数据。这也要求我们的 连接是多线程安全的。
(,)rrrrrrr提供绕开 组件直接从 连接同步接收数据的功能。比如,客户端需要上
传一个 (-,我们可能希望直接从 连接进行接收数据,这是有好处的,后面可以看
到。
这里列出的是 组件的主要职责,还有很多细节性的没有罗列出来,如果一个
组件解决了上述所有问题,对我来说,应该就是一个很好用、很适用的 组件了。
. 组件接口定义
相信很多朋友和我一样,刚接触 服务端开发的时候,通常是当一个 连接建
立的时候,就分配一个线程在该连接上监听请求消息,这种方式的缺点有很多,最主要的
缺点是效率低、管理复杂。
我的最初的 组件是 ..版本的,那时很有幸接触到了 "" 平台上最高效的
通信模型――完成端口模型,完全理解这个模型需要点时间,但是《/+多线程程
序设计》(侯捷翻译)和《"" 网络编程》这两本书可以给你不少帮助。异步机制是
完成端口的基础,完成端口模型的本质思想是将0启动异步操作的线程0和0提供服务的线
程0(即工作者线程)拆伙。理解这一点很重要。在 中没有对应的组件或类对应于完
成端口模型,解决方案有两个:一是通过 1$ # 来实现自己的完成端口组件,另一种
方式是通过 的现有通信设施来模拟完成端口实现。
本文给出第二种方案的实现说明,另外,我也给出通过“异步+线程池”的方式的 组
件实现,这种方式对于大并发量也可以很好的管理。也就是我,我的
! 类库中,有两种不同方式的 组件实现,一个是模拟完成端口
模型,一个是“异步+线程池”方式。无论是哪种方式,它们都实现了相同的接口
$。$ 这个接口涵盖了上述的 组件的所有职责,这个接口并不复杂,如果理解
了,使用起来也非常简单。我们来看看这个接口的定义:
2-(3!$4$5$ 65$(((
7
2789当前连接的数量
9
这个接口继承了另外三个接口,
$5$ 65$(((。$ 接口是为了统一基于 和 的
通信组件而抽象出来的,它包含了以下内容:rrrr$:!&%! 就是我们上
述图中的消息分派器,这是 通信层中的中央,它的重要性已从前面的关系图中可见一
斑了。$:!&%! 需要在初始化的时候提供,或者通过 %! 属
性通过 $; 容器进行设值法注入。<!(! 属性用于决定当用户的第一个请求不是
登录请求时,是否立即关闭 连接。其它的属性已经加上了注释,非常容易理解。
$ 6 接口说明了 组件应当发布的事件,主要对应于前述 组件职责
的()(+)()点。其定义如下:r
每一个在线用户都对应着一个 连接,我们使用 连接的 '! 作为
$% 来标志每一个连接。= 将用户与服务器的交互分为三类:登录、退
出和标准功能访问,如以下枚举所示。rrrr这个接口中的方法的含义是一目了然的。
上述的几个接口已经完整的覆盖了前述的 组件的所有职责,在了解了这些接口定义的基
础上,大家已经能够使用 ! 类库中的 组件了。如果想复用的不仅仅
是 组件,而是整个 通信层,你就需要关注后面的内容。不管怎样,为了文章的完整性,
我在这里先给出前面提到的 组件的两种实现。rr
>2&&!?@
$!3"#!&线程安全的网络流r。
剩余10页未读,继续阅读
资源评论
- koala_yqf2013-07-15框架思路不错,值得借鉴
yulien
- 粉丝: 9
- 资源: 70
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功