对于通讯部分框架设计的几点思索

通信者,产品之大事也,死生之地,存亡之道,不可不察。——《唐子兵法》

 

激动啊,最近成立了的团队,开发我们自己的产品,新手初来乍到,软件的通信部分框架是我和另一个小伙伴花了差不多一晚上讨论出来的,又花了两个通宵以登陆功能为例把流程实践了一遍,还算合理,在此把几天来的部分开发心得和大家交流一下,如有不合理或考虑不周之处也请大家多多指教。

首先简单介绍一下我们的产品——时间银行。这是一个在国外已经流行几十年的点子,旨在鼓励人们互相帮助,增进诚信与消除社会不公。举个简单的例子,张华是一位理发师,它免费帮李萍理发一小时,他就可以把这一小时作为时间币存到时间银行里;如果哪天张华有需求,比如想要找人帮忙修理电脑,那么他就可以把这一小时取出来,比如联系到IT专家李明,帮他修电脑一小时。我认为,这种模式相对于资本主义简单粗暴的分配方式有它的合理性,也很有社会价值,因此值得推广。我们的产品想要打造的就是这样一个社区: 用户可以在平台上任意发布需求信息,用户之间可以通过简短的交流,约定好现实中的时间,通过我们的银行实现志愿服务的交换,也增进社区成员之间的友谊。

其实最开始,我们还把自己做的东西定义为一个通信项目,但是后来想想发现这其实是个伪命题:在这个互联网时代,放眼天下,哪个软件不带通信功能? QQ、微信这种即时通信软件那就不说了,就算是PSCAD这种NB烘烘的单机软件,也会有自己的后台反馈模块,及时向服务器返回用户操作与bug信息,这些数据可都是bug修正和功能优化的宝库啊,而且在这个个“大数据时代”,数据的价值更是与日俱增,前途不可限量。所以说,终端与云端的通信是一款产品的生命所在,没有了通信功能,再好的软件也会暗淡无光,这点从哲学层面上也是容易理解的。。。

咳咳,好了,前面吹了这么多,其实就一句话:通信功能很重要,在项目初期一定要认真考虑。以下是我总结的通信部分需要讨论的几个问题,下文中也会据此一一讨论(借鉴一下马志丹学长的博客格式哈):

1 通信功能本质上要实现什么?

2 通信的核心问题有哪几点?

3 如何实现通信模块与其他功能模块的分离?

4 生产消费模型思想与具体实现

5 产品开发后期与上线运营后需要考虑的几个重要问题

 

1 通信功能本质上要实现什么?

在讨论这个问题之前,我们不妨先来梳理一下我们在初学单机软件开发时的框架思路:



 

1 单机软件基本框架

其实,单机软件的框架思路我们可以简单总结为上图(from Diagram Designer,水平有限画的可能不好看,请多多见谅):

以五子棋程序为例,程序运行时,会显示一个界面(UI),上面会有棋盘和其他的东西;当我们鼠标点击棋盘时,加在组件上的监听器(Listener)会收集到鼠标点击的坐标数据;后台处理程序(Processor)根据坐标信息,调用绘制棋子的程序,在界面(UI)上对应的位置画上棋子,一个简单的单机五子棋下棋功能就此实现。其他功能类推之,个人感觉大同小异。

那么,需要通信的软件框架思路又如何呢?



 

2 通信版软件基本框架

 

上图就是我理解的通信软件的基本框架。细心的你一定发现了,这里终端A和终端B的结构和上面单机版几乎完全相同,唯一不同的就是多了一条连接云端的通道——没错,在通信软件框架里,终端之间可能需要得到各自的信息,因此常常需要云端(Server)作为中转站:



 

3 通信版五子棋流程

 

同样是以五子棋为例,现在我们要做一个通信版五子棋,实现在线对战,那么在我点击我的屏幕时,只在自己的屏幕上显示一个棋子就远远不够了,因为对手的屏幕上也要同时显示这个棋子,因此,对手的程序也必须接收到我点击屏幕的坐标数据才行。不过目前来讲,实现这个基本还只能依靠网络通信——常用的解决方案是终端后台程序(Processor)把我点击的坐标数据通过网络托管到云端(Server),也就是我们常说的服务器,再通过这个通过服务器把坐标数据分发到我对手的程序中,再由对手的终端上的Processor程序处理,把棋子显示到他的屏幕上;与之对应的,对手的程序也会把他的下棋坐标信息发到我们的客户端程序中,在我的屏幕中显示,于是,一个实用的在线对战五子棋程序就华丽诞生了!

好了,通过以上分析,我想你应该有这种感觉——其实,通信软件不过如此,就是把终端的部分后台程序统一托管到云端服务器而已!



 

4 终端后台与云端后台

事实上,只要终端与服务器能识别彼此发送的数据,保证终端发送的数据服务器能原封不动地还原,或者相反(比如我的终端发送了我的下棋坐标后,服务器能正确得到我的下棋坐标),那么,忽略终端与服务器之间的网络,对于每个终端本身来说,云端的后台程序(Processor)就好像和自己的后台程序(Processor)连在一起一样。(不懂的童鞋多想想,博主暂时只能帮你到这了)

 

而通信部分,本质上只要保证经过网络传输数据信息在传输前后没有变化(甚至有些情况下只要相差不大)即可,通信程序只起到搬运工的作用!



 

5 通信模块只起搬运工作用

 

2 通信的核心问题有哪几点?

这个问题的答案,要我总结只有两点:唯一标识通信协议问题。

唯一标识,举个通俗的栗子就是电话号码。我们知道,我们如果要打电话,知道彼此的电话号是一个很必要的前提,因为在现今移动联通电信三家运(hei)营(xin)商(fan)统治之下,天朝近14亿人被准确地对应为十几亿个电话号码,和身份证一样,一个萝卜一个坑错不了,因此运营商可以根据我们的号码准确接通彼此,而不是打到别人那里(除非你拨错号了)。

与电话类似,所有运行在互联网上的程序,也必须通过一套规则统一编号,赋予唯一标识,才能保证任何程序能通过网络彼此通信。所以,把如何为每个未来可能通信的程序赋予唯一标识作为通信核心问题讨论一点不过分。当然,在现今最通用的TCP/IP协议框架下,程序的这个唯一标识就是IP + 端口号。(虽然很想向你们详细介绍TCP/IP协议,但可惜博主也在研究ing - . -

通信协议,同样举个通俗的栗子,就是我们每天说的普通话。不知道你有没有思考过,普通话就是一套规则,正是通过它,我们可以利用声波向别人传达信息并理解别人表达的信息,也就是实现人与人之间的通信——但前提是我们都通晓它的一套规则,知道每句话的每个发音是什么意思: 来自北方的孩纸们想必都有过这种经历,那就是南方的室友在打电话时,当他们放心大胆地切换到方言模式时,你会瞬间有种泪奔与被无视的感觉——没错,这就是不知晓通信协议的后果TOT

因此,与说话类似,网络通信的程序之间也必须事先商议一套规则,也就是通信协议,这样才能保证通信双方所有信息正确的传达,使得通信畅通有效。所以,通信协议的合理制定是保证通信顺利进行的关键,自然要作为核心议题讨论了。使用TCPUDPHTTP还是自定义的协议,发送的数据包中每个变量是什么含义,每个字符串按什么规则发送,甚至有必要的话深入到IO流上的每个字节、网线上的每个01信号的含义等等,都必须要有一套明确的协议规定。而且切记,协议一旦讨论完成不要轻易改动,后果参见上文中北方孩纸的悲剧。

 

3 如何实现通信模块与其他功能模块的分离?

有一点大家应该达成共识,那就是大多是数情况下,通信模块的功能是与其他模块互不干扰的,因此我们能够而且有必要把通信模块与其他模块隔离开,特别是在团队开发中。

不得不承认,这个议题确实涉及到所谓的设计模式的问题。但是本着不想被过早被束缚思路以及个人对设计模式的某些偏见,我没有急着搜什么《23种设计模式》啊啥的,而是自己对这个问题认真分析了一番。

 

在问题1中,我已经说过,通信模块只起到搬运工的作用,因此,我们的后台程序不需要知道通信模块具体实现,只要会使用它成功传输过来的数据就好。因此,我们使用数据包(Package)类作为信息载体,栗如,只要保证服务器端接收到的请求数据包(LoginPackage)与客户端发送的请求数据包(LoginPackage)没有不同,服务器就和直接操作客户端的数据包没有不同,因此,设计整套后台程序(终端+云端)时,我们完全可以忽略通信模块:



 

6   忽略通信模块的软件框架

 

然后我们再开单独分析一下通信模块的设计:

 

在问题2中,我们讨论了同喜你的两个核心问题——唯一标识与通信协议。唯一标识问题,TCP/IP协议已经基本为我们解决了,我们使用IP+端口号即可。所以我们要解决的就剩通信协议的制定与实现了。

上文中我们提到过,普通话或者说一门语言就是一种通信协议,所以,我们可以试着把我们通过语言通信的过程做如下分解:



 

7 普通话沟通的过程

其实,在语言交流过程中,我们的嘴和耳就充当了通信模块的作用:一方面,嘴作为信息发送者,按照普通话规则把想说的话变成声波说出;另一方面,耳作为接受者,同样按照普通话规则把听到的声波转化为别人说的话,而只要保证耳说出来的话和嘴说出来的话一致,我们的通信就是畅通有效的。而至于听到的话如何理解,就不是嘴和耳的事了,那是大脑(也就是后台程序)的事。

同时,我们也不难理解,通信协议在这个过程中有多么重要了。



 

单独的通信模块框架

 

在这套框架里,Sender就相当于嘴巴,Receiver相当于耳朵,终端和云端各有自己的嘴巴和耳朵,只要两侧使用的协议相同,而且网络正常,就能保证通信畅通。注意,这里所有与通信协议相关的操作都是由SenderReceiver承担,也就是说,即使日后要改变通信协议,也只改变SenderReceiver即可,终端和云端的其他部分不受任何影响。比如,我们当前采用的是基于字节流的socket通信协议,日后我们如果想改成HTTP协议,也是轻而易举的。

 

最后展示一下我们当时最终定稿的框架:



 

9  我们项目的基本框架

我了大家看得明白,我以部分登陆流程为例,向大家解释一下我们的项目框架:

1 当用户点击登陆按钮时,界面监听器(Listener)会从界面(UI)得到用户输入的用户名密码,并打包成登陆请求数据包(LoginPackage

2 数据包被发给专门向外发送数据包的发送者类(Sender),由它按照协议把数据包中内容转为字节流通过网络传输

3 云端服务器中专门等待接收客户端发来的消息包的接受者类(Receiver)读到写入的字节流数据,按照协议重新还原成登陆请求数据包(LoginPackage

4 云端后台程序(Processor)得到登陆数据包,把用户名与密码与数据库比对,并生成登陆结果数据包(成功或失败),由云端的发送类(Sender)按字节流发送到对应的终端

5 终端的接收类(Receiver)又将字节流数据按照协议打包成登陆结果数据包(ResultPackage

6 终端的后台处理程序(Processor)得到收到的登陆结果数据包(ResultPackage),判断后得知是否登陆成功

 

4 生产消费模型思想与具体实现

生产消费模型,在通信中是很重要的一个概念,它借用了生态学中的概念,很形象地描述了通信过程中的信息流通过程: 比如在图8中,比如我们的监听程序可以看做信息的产生者,它可以产生登陆数据包(LoginPackage),负责向外发出信息,而我们的云端的后台程序就可以看作消费者,负责处理登陆数据包(LoginPackage),使用外界发来的信息。这就是生产消费模型简单的栗子了。

其实不光是通信部分,任何程序都可以借用生产消费模型这种思路分析,弄清楚谁是生产者,谁是消费者,思路会更清晰。

生产消费模型博主打算日后专门写篇博客展开分析,希望大家下持续关注!

 

5 产品开发后期与上线运营后需要考虑的几个重要问题

说实话,这个问题我是没有资格分析的,毕竟我们的项目刚刚启动,距离上线还很远,所以只是把我暂时想到的几点问题在这里列出,也方便日提醒自己与小伙伴们。

 

1 数据安全问题: 这个很重要,所有的用户名密码等数据不能明文存储,一定要经过加密等操作,最常见的是使用MD5摘要算法,有兴趣可自己百度,博主日后也会专门讨论。

2 注册入口问题:在这个APP爆炸的年代,频繁的登陆注册是令每个用户头疼的问题,因此考虑合作账号登陆就显得十分有必要了,在注册时提供QQ、微信、微博等合作账号注册入口是很明智的选择。

3 协议安全问题: 这个问题同样很重要,协议在设计时应充分考虑到安全问题,如果协议被轻易破解,那么呵呵,后果可以自己想象。

4 服务端框架问题:上文中,我只是把云端服务器当作部分终端部分后台程序的托管,或者中转站,但是其实服务器要考虑的问题时很多的,不得不认真设计,比如对于不同在线用户量,服务器的架构也是相差很大的,详情可参考腾讯大讲堂:一亿在线背后的技术挑战;

 

再比如说并发问题时消息队列的处理,或者说我们现在讲的中间件等等,这些也是不得不考虑的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值