引言

即便在通讯如此发达的今天,IM 也依然是诸多场景下非常重要的基础能力。因此做为 一名 Android 开发,不可避免的会遇到一些IM 相关的需求或问题。本文以一个Android开发的角度来讲述IM 开发相关的基础知识。
 
想要阅读更多技术干货、行业洞察,欢迎关注网易云信博客
了解网易云信,来自网易核心架构的通信与视频云服务。

IM开发需要面对的问题

  1. 网络问题,如何高效快速的传输数据?
  2. 协议问题,消息如何封装?
  3. 及时性问题,如何进行进程保活?

网络问题

  TCP 的三次握手建立连接是一个非常耗时的过程。在 IM 场景下,数据的传输将会非常的频繁,如果每次传输都建立一个 TCP 连接,那么这个效率是不能接受的,并且频繁的建立连接可能会发生socket错误,所以我们需要 “复用”TCP连接,也就是平时所说的TCP长连接。
TCP 长连接
短连接在建立后,当数据传输完毕时会立即关闭,下次需要传输数据时需要重新建立连接,在日常的业务场景非常常见,比如通过 http/https 请求获取Server 数据。而长连接在传输完数据后并不会关闭,这样下次需要传输数据时就可以直接使用已经建立好的连接,这中间省去了连接建立的时间。但是建立一个 TCP 长连接却并不是“建立后不关闭”那么简单,因为 TCP 长连接会“被动”关闭。
网络地址转换 (NAT)
   IPv4的容量是有限的,随着接入Internet的计算机数量的不断猛增,IP地址资源也就愈加显得捉襟见肘,于是也就产生了 NAT技术。简单来说,NAT就是在局域网内部网络中使用内部地址,而当内部节点要与外部网络进行通讯时,就在网关(可以理解为出口,打个比方就像院子的门一样)处,将内部地址替换成公用地址,从而在外部公网(Internet)上正常使用,NAT可以使多台计算机共享Internet连接,这一功能很好地解决了公共 IP地址紧缺的问题。通过这种方法,可以只申请一个合法IP地址,就把整个局域网中的计算机接入Internet中。
  而我们就处于运营商(移动/联通/电信。。。)的局域网内。当我们接入运营商的网络后,会分配到一个运营商的内部 IP地址,于是我们就可以使用这个IP地址建立连接向外传输数据了。但是当这个IP闲置了一段时间(NAT超时时间)后,运营商为了节约资源,会把分配给我们IP回收掉。此时如果我们还继续使用之前那个未关闭的连接去传输数据,那么毫无疑问会失败的。下面是一些运营商的 NAT超时时间。
网络NAT超时时间中国移动3G/2G5 min中国联通2G5 min中国电信3G大于 28 min
   要想长连接一直有效,那么闲置时间就不能太长,所以在闲置时我们需要向外(Server)传输一些数据包,这也就是常说的“心跳包”,用于告诉运营商这个 IP 还在被使用,告诉Server 客户端还在线。
心跳策略
  心跳策略一般分为两种:
    1. 固定心跳
    2. 动态心跳
这里讲一下固定心跳,动态心跳可以参考 微信心跳 。固定心跳其实就是间隔固定时间发送一个心跳包。
 
心跳间隔 X 的值需要参考运营商的 NAT 超时时间确定,不能大于最小的 NAT超时时间,也不能太小,要不Server 的负担非常重。一般取一个比较接近最小的NAT超时时间,比如4分钟。

协议问题

   协议决定是消息以什么样的形式传输,即发送时如果对消息进行封装,接收时如何解析。比如可以将消息体以 XML 的形式进行处理,这也就是 XMPP 协议,参考下面一个消息示意:
隔壁老王:你儿子长的比你帅多了。
老李:嘿嘿,谢谢夸奖!
<message>
<from>隔壁老王</from>
<to>老李</to>
<context>你儿子长的比你帅多了。</context>
<type>text</type>
</message> <message>
<from>老李</from>
<to>隔壁老王</to>
<context>嘿嘿,谢谢夸奖!</context>
<type>text</type>
</message>
  从上面的消息示意,我们可以发现一条消息的内容可以拆分成很多属性,而协议就是把这些属性组合起来。
以 XML 的形式传输消息,最大的一个问题,就是冗余数据太多了,特别是当消息的属性比较多时。
  那么有没什么格式能尽可能有减小冗余数据?
  其实无论消息如何封装,最终传输的肯定是二进制流,那么完全可以直接用二进制的形式对消息进行封装,这也就是二进制协议。下面是一个简单二进制协议的实现示意。
  一条消息由from + to + context + type这几个属性组成,那么我们完全可以按顺序存储在二进制中,由于内容长度不确定,所以每个属性的开头我们可以使用固定字节数来记录这个属性的内容长度。当然,这里只是展示了一个二进制协议的例子,实际的消息会比这复杂多了,但是核心思路就是这么简单,最终无非是设计与实现形式上的差距。

及时性问题

  IM的作为即时通讯,如果无法保证消息及时触达,那么意义就大打折扣。要保证消息及时触达,最关键要做到以下两点:
   1. App 进程要尽量存活,也就是进程保活 ;
   2. 在 App进程挂掉后,能够唤醒起来;
进程保活
  进程保活其实是属于 Android 平台的一个话题,相信大家日常开发也遇到过,细节就不在这长篇大论了,简单的说下几个原则:
   1. 优化内存,减小内存的占用,会大大的减小被 kill 的机率;
   2. 多进程,将 UI 进程与 IM 进程独立出来,这样 IM 的进程负担就会小很多;
进程唤醒
  严格意义上来说进程唤醒是属于进程保活的一个分支,这里单独列出来,是因为进程唤醒关注的是进程挂掉之后的动作。对于进程唤醒,这里也只列些原则,详细的可以去查阅相关资料。
   1. 静态注册监听广播(<7.0)
   2. Alarm定时任务,定时去检查进程是否存活。
   3. JobScheduler定时任务,定时去检查进程是否存活( >5.0 )
   4. 接入厂商推送
 
网易云信(NeteaseYunXin)是集网易18年IM以及音视频技术打造的PaaS服务产品,来自网易核心技术架构的通信与视频云服务,稳定易用且功能全面,致力于提供全球领先的技术能力和场景化解决方案。开发者通过集成客户端SDK和云端OPEN API,即可快速实现包含IM、音视频通话、直播、点播、互动白板、短信等功能。

Android开发需要了解的 IM 知识的更多相关文章

  1. Android开发学习必备的java知识

    Android开发学习必备的java知识本讲内容:对象.标识符.关键字.变量.常量.字面值.基本数据类型.整数.浮点数.布尔型.字符型.赋值.注释 Java作为一门语言,必然有他的语法规则.学习编程语 ...

  2. android 开发概述以及相关背景知识

    参考链接:http://www.runoob.com/android/android-architecture.html http://www.runoob.com/android/android-a ...

  3. 【Mood-12】Android开发相关书籍推荐

    新年伊始,找到Android进阶干货若干,2015拜读. 1.Android应用UI设计模式 目前,谷歌Android操作系统在移动市场中风头正劲,并且未来发展势不可挡.<Android应用UI ...

  4. Android开发入门经典实例

    开发实例概述 今天带大家做一个简单的Android App,这个App会显示创新工程实践老师们的照片和信息,不妨先看一看效果: 虽然这个App非常简单,但是涉及到了Android开发中的一些关键知识, ...

  5. 【Bugly 技术干货】Android开发必备知识:为什么说Kotlin值得一试

    1.Hello, Kotlin Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 1. ...

  6. [转]【eoeAndroid索引】史上最牛最全android开发知识汇总

    一.开发环境搭建 (已完成) 负责人:kris 状态:已完成 所整理标签为:搭建 SDK JDK NDK Eclipse ADT 模拟器 AVD 调试器(DEBUG) DDMS 测试 日志 Logca ...

  7. Android 开发知识体系

    知识体系 1.Unix/Linux平台技术:基本命令,Linux下的开发环境 2.企业级数据库技术:SQL语言.SQL语句调优.Oracle数据库技术 3.Java 语言核心技术:Java语言基础.J ...

  8. Android开发——Fragment知识整理(二)

    0.  前言 Android开发中的Fragment的应用非常广泛,在Android开发--Fragment知识整理(一)中简单介绍了关于Fragment的生命周期,常用API,回退栈的应用等知识.这 ...

  9. Android开发——Fragment知识整理(一)

    0.  前言 Fragment,顾名思义是片段的意思,可以把Fragment当成Activity的一个组成部分,甚至Activity的界面可以完全有不同的Fragment组成.Fragment需要被嵌 ...

随机推荐

  1. python栈--字符串反转,括号匹配

    栈的实现: # 定义一个栈类 class Stack(): # 栈的初始化 def __init__(self): self.items = [] # 判断栈是否为空,为空返回True def isE ...

  2. Android中的事件处理研究

    处理用户界面事件Handling UI Events 在Android上,不止一个途径来侦听用户和应用程序之间交互的事件.对于用户界面里的事件,侦听方法就是从与用户交互的特定视图对象截获这些事件.视图 ...

  3. windows 路径

    windows下的路径分隔符是\,而不是/ hosts文件的位置:C:\Windows\system32\drivers\etc 安卓(Android)用户:Android手机hosts文件路径:/s ...

  4. 史上最全最强SpringMVC详细示例实战教程【good】

    1)Spring MVC 在调用处理方法之前,在请求线程中自动的创建一个隐含的模型对象. 2)调用所有方法级的 标注了 @ModelAttribute 的方法,并将方法返回值添加到隐含的模型对象中. ...

  5. Leetcode 171 Excel Sheet Column Number 字符串处理

    本质是把26进制转化为10进制 A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 class Solution ...

  6. bootstrap学习之路

    接触bootstrap也半年有余,从一开始不知道如何使用,到知道其各个模块的具体功能,再到提炼哪些使用的比较多,再此又体会到bootstrap源码的精髓,通过oocss写的类使其感觉更有易用性,开始本 ...

  7. Java之nio性能比较

    结果:used time:53574684used time:1800077620used time:12563690可见MappedByteBuffer读写数据是最快的, 其次是FileChanne ...

  8. SVN如何迁徙到Git

    由于一直都是采用SVN作为源码管理,转到Git不能从头开始吧~~下面就具体说说如何将SVN已有的项目工程迁徙到Git上面 步骤 (1) 安装Git客户端程序(2) 将SVN上面的工程通过Git克隆到本 ...

  9. iPhone开发笔记(20)EGOImageView的使用方法及注意事项

    EGOImageView是一种实现网络图片的异步加载和缓存的第三方类库,具有相同功能的第三方类库还有SDWebImage.但是相比两个类库的安装和使用来说,EGOImageView更简单一些,下面就介 ...

  10. Bootstrap 添加到项目

    至少在项目中添加以下三个文件 1 添加css文件  <link href="~/Bootstrap3.3.7/css/bootstrap.min.css" rel=" ...