【Tech-IM】IM类型app开发浅谈(一)---聊天中的消息处理

        早在一年之前,就曾负责一款IM移动通信类型的App开发,部分相关的功能都是仿照微信来进行,例如:聊天,通信录,朋友圈

等。由于,整个团队都没有IM方面的经验,我们只能不断地摸索前进,所以这篇文章也只适合初级IM开发者来参考之用。

        对于开发一款App,即是成立一个先的项目组,对于前期的立项,需求确定,资源分配就直接跳过,那些是属于项目管理与产

品经理的范畴。我们就直接进入开发阶段。

   

       1.首先确定需求,这里我们称之为功能,对于程序猿来说更贴近一点。

  •   聊天 ,其中包括单聊,群聊。
  •   通讯录,其中包括加好友,验证好友。
  •   朋友圈,其中包括时间线,图片上传下载,及保存。 

        2.前期重要功能确定之后,就是系统框架的搭建。

  •   服务器端: 消息系统,用户系统,朋友圈系统
  •   客户端端: 消息管理框架,通讯录管理框架,朋友圈管理框架

    

        3.确定开发次序,就是开放进度。

 

        4.不断发现问题,不断改进。


       

        以上四点是基本开发一个app的过程,以下就述说一下我们其中在开发过程中遇到的一些问题,和开发一款IM的摸索中的思路。

  

        一,对于程序猿来说,确定需求就是确定功能。聊天功能,包括了一对一的聊天,多人的聊天。一对一的聊天,就是把消息推

送到另一个客户端的过程。群聊,就把消息推送多多个客户端。那么我们聊天功能中主要要考虑哪些问题呢?

  •  消息推送
  •  消息安全
  •  消息离线
  •  语言聊天
  •  图片传输 
  •  消息掉包
  •  消息格式           

       1.消息推送。 我们都是知道聊天系统中必定有消息推送系统,意义就是客户端与服务器端保持一个长连接,然后就服务器管理着

每一条这样的Socket长连接,当消息中心有该客户端的消息的时候,就会推送给客户端。这里推送模式首先就涉及了常见的三种方

式:1.定时轮询,主动拉取消息,2、socket推送消息,3、socket通知,主动拉取消息。

  •       定时轮询,主动拉取消息 。 该模式更多适合广告方面的用途。例如我之前做的广告SDK中的banner,插屏等。如遇到需要更新广告信息的时候,就会定时重复去请求服务器,返回服务器所需显示的广告内容。又或者做单机支付的时候,由于三大运营商的审核标准都不一致,我们需要控制这些单机游戏在进行游戏道具购买的时候,用的是第三方平台支付还是短信支付时,都会用到定时轮询,主动拉取消息。由于,我们是即时通讯应用,如果是去主动拉取的话,那么就需要我在我们应用中开启轮询线程,每次都去问服务器是否又消息更新。这里就涉及到一个流量问题,和性能问题。性能问题:因为不断主动使用Http请求,会耗电。
  •       socket推送消息。 socket推送就是消息推送的主要实现途径。之前做游戏客户在线帮助功能的时候,就利用socket与服务器保持长连接,然后单线程地与服务器进行消息交流,为何是单线程?因为socket受到消息是阻塞的,这里涉及了socket通道的问题,随后再说。客户端登录成功后,与消息服务器保存一个socket长连接,当消息服务器收到指向该客户端的消息时候,再通过这个socket推送给这个客户端。   socket感觉就是为了即使通讯而出现的。但是由于移动网络的好难以稳定的,在网络差的时候,这种socket链接并没有Http那么强壮,很容易出现掉包
  •       socket通知,主动拉取消息。第一次接触这个模式,是看到一个分析与借鉴微信消息推送的一篇文章。主要通过socket与服务器维持通讯,这个通讯包含的协议比较特别,比心跳包外还加入一个功能Id,这个功能ID,主要是服务器返回,当服务器返回这个功能ID的时候,证明这个功能有消息更新,然后再去通过http接口,上去服务器拉取更新的内容。这种模式,完美的结合前两个者的风格。这种方式第一还是可以与服务器保持着一个长链接,第二消息推送的http响应比socket健壮得多,也就是掉包率会减少。因此,还是建议使用第三种。但是,这里会涉及到另一个问题。

          以上是消息推送客户端与服务器端之间的通讯机制,消息推送中另一个重要的关键因素------消息协议。目前市面上,即百度上出

现的基本都是xmpp或者mqtt这两种协议。 xxmp使用的是传统的xml文本形式的数据类型作为通讯协议,这种xml形式在前几年基本

都会应用到所有的IM类型应用,因为其开源方式和google官方使用的推送作为例子的 广泛认知,基本上这种方式成了主流。包括早

其的米聊,前期也是使用xmpp的协议。最具代表的就是极光推送了。但这种形式的xml格式借用了太多的数据流量,在现在这个通

讯数据那么多的情况下,会耗费掉大量流量。所以我们放弃掉。

       最后,我组的后端工程师找到了另一套开源的消息管理机制---------ActivityMQ。这个开源的框架的好处是支持自定义协议,它的

框架只会帮你处理一件事:保存你的消息队 列,向你目的的socket发送消息,而且,它也是 开源的 ~!因为其为我们提供了所需的消

息管理机制,我们服务器就不再为消息发送的机制来进行过多的开发,当然,开源的 嘛,很多东西还是需要改为自己项目上需要

的。  而,真是这个服务器消息框架,促使我们暂时放弃了第三种消息推送机制。为何呢?请继续往下。
    
       消息推送机制上,我们还是选择了第二种,只用socket来进行推送,这样服务器与客户端的逻辑就会变得鲜明一点,如下图:


    
      上图可知,签收消息,是为了让服务器知道,客户端已经顺利接受了这条消息了,服务器可以在消息队列中把该条消息移除了。

没有这个签收机制的话,服务器的推送消息 队列中会一直保留这条消息,会一直发送。为何要引入 签收机制 ?因为在移动网络或者

任何网络情况先,并不能预知是否服务器的信息顺利呈现给了客户端用户的。其中的 情况可能是,消息发送到了客户端了,但是可

能客户端在保存入数据库或者解释数据是出错,那么这条消息就会消失掉,我们俗称“被吃了”,并且在网络传输中,肯定会出现一

一定程度的掉包情况,所以这个签收机制就变得必不可少了。

      而第三种的方式,服务器与客户端之间的逻辑大致如下:


         由上图可知,第三种推送机制,类似于TCP协议一样,通过三次握手来确定一次会话,但正是这样的机制,其中包含多了两个步

骤,因此我们在未确定我们的App的将来规 模以及时间的关系,我们果断采用省时省力的第二种,但我们深深地知道,当下一次大版

本来的时候,需要转换成第三种方式,原因上述已经说过了。
     

        对于消息安全,就是防止一些非法黑客,对我们客户端与服务器端会话进行抓包。所以我们需要对我们的会话的数据进行加密,

看过微信的加密方式我们都知道,首先,微信是利用第三种消息推送机制,他们每一次握手的过程可以与服务器交换一个新的

SyncKey来进行信息加密,这种动态加密方式,强化了消息传输中的保密性,非常值得借鉴学习,而且这种机制对于消息状态同

步,增量,有序传输等需求都能满足。长连接通知/短连接获取与确认的方式是最应该被推荐了,但时间关系,我们就使用简单的

Token加密,非常危险的方式,一旦给人获取到Token的信息与加密方式,这种密文就没有任何意义。


       消息离线,服务端收到要将客户端A发出的消息发送给客户端B的时候,B并不在线,就是说,B并没有与服务器有

socket链接。此时应当怎么处理消息呢?我们可以把这些未经过签收的消息,放置在一个新的消息队列中。当客户端

下次链接服务器的时候,就先调用这个未接收的消息队列中的信息,然后发送给客户端。所以我们利用userId和与

token标示一个消息,再查找这种未签收的消息就利用userid查找,然后校验token,验证用户是否在线,在线,发出。

 

     语言聊天,可以参看我之前的两遍博客--- Speex的使用Speex代码实现

        

      图片传输,聊天的过程中,会出现图片传输,但由于现在手机拍摄的图片都很大,基本是1M~3M之间的大小,如

果每次都传输1M以上的图片,不但其中会掉失的数据验证,而且也会占用客户端大量的上行带宽,所以这里对于图片

需要压缩,并且有可能需要分包传输,所以这部分放到下面和消息格式,即消息协议一起讨论。


      消息格式,下次再码字。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值