背景
最近我们的团队正在开发一款面向移动平台的LBS应用,客户端有android、j2me版本,LBS的概念非常不错我们希望将其发挥带极致。本人在这个项目中主导服务器开发(java平台)。由于人手有限以及团队中各自专长不同,服务器的数据统计与将来的PC端也又我一人用.NET承包了:P好了,废话不多说我们直入正题。
其实有人会认为,不就是客户端与服务器的通信嘛,很简单,如果用阻塞I/O的话开两根线程,一根从网络I/O中读取数据,将每条消息投递到一个消息队列中,然后通过一些触发机制触发这些消息的处理代码;要写的话将要写的代码投递到一个输出队列中,另一根线程从这个队列poll消息然后write到流中即可……是的,这么做可以,而且我们android端的通讯就是这么做的。不过我还有一个目的,就是借此写一个轻量级的.NET服务器(之前是用java nio做的服务器),做过服务器的人都清楚,服务器是不可能用阻塞I/O+多线程的。而且我需要的是一个一个可服用、可定制的灵活的服务器/客户端通讯框架,于是就有了这个通信框架。如果您研究过apache mina,会发现在api的设计上与mina有相似之处哦。
在项目中的运用
软件的设计与架构是一门技术也是艺术,将整个合理的分层、熔炼,我们可以方便的在后期独立更换协议、业务、UI、配置。
其中:ClientConnLib是基础的通信框架;ConnProtocolLib结合特定协议的ClientConnLib的一个实现;BizModule则是基于通信框架接口的业务模块;BackEarth则是一个WPF应用程序,整个项目采用MVVM结构,BackEarth相当于MVVM中的View和Model。本系列文章只讲其中的客户端通信基础和急于这个框架的协议库实现。
原理概述
如下图:来自网络的数据会被Decoder处理,IDecoder接口有两个方法:Decodable和Decode,Decodable负责判断消息的完整性,如果接收到了一条完整的消息则在Decode中进行处理(传递到MessageHandler的MessageReceived)
ClientConnLib本身并不规定具体的协议格式,如果要定制的话只需自行实现IDecoder、IEncoder和IoHandler即可。
定制协议库
基于ClientConnLib我写了个ConnProtocolLib用于与我的java服务器进行通讯,我的那个服务器通讯协议时这样的
消息头是6个byte,前4个byte是消息的总长度,用于IDecoder进行完整性验证,后2个byte是消息的id,其余的是消息体数据。完整的消息读出后会被放入一个NetworkMessageBase的对象中传递给MessageHandler.MessageReceived处理,当然这个传递时借助一个线程池完成的,这样I/O线程解析完消息后会呗即时释放,业务的处理交由其他线程来完成。
这里我除了有一个NetworkMessageBase还有一个类似的JpNetworkMessageBase,后者是针对大字节序平台写的比如java platform,如果通讯目标使用大字节序则使用JpNetworkMessageBase即可。
余下几篇篇我将讲解这个通讯框架和协议库德实现。
下载链接:
http://files.cnblogs.com/wJiang/ClientConnLib.rar