引言
即使在通信如此发达的今天,IM 也依然是诸多场景下很是重要的基础能力。所以作为 一名 Android 开发,不可避免的会遇到一些IM 相关的需求或问题。本文以一个Android开发的角度来说述IM 开发相关的基础知识。
了解
网易云信,来自网易核心架构的通讯与视频云服务。
IM开发须要面对的问题
-
网络问题,如何高效快速的传输数据?
-
协议问题,消息如何封装?
-
及时性问题,如何进行进程保活?
网络问题
TCP 的三次握手创建链接是一个很是耗时的过程。在 IM 场景下,数据的传输将会很是的频繁,若是每次传输都创建一个 TCP 链接,那么这个效率是不能接受的,而且频繁的创建链接可能会发生socket错误,因此咱们须要 “复用”TCP链接,也就是平时所说的TCP长链接。
短链接在创建后,当数据传输完毕时会当即关闭,下次须要传输数据时须要从新创建链接,在平常的业务场景很是常见,好比经过 http/https 请求获取Server 数据。而长链接在传输完数据后并不会关闭,这样下次须要传输数据时就能够直接使用已经创建好的链接,这中间省去了链接创建的时间。可是创建一个 TCP 长链接却并非“创建后不关闭”那么简单,由于 TCP 长链接会“被动”关闭。
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 客户端还在线。
这里讲一下固定心跳,动态心跳能够参考
微信心跳 。固定心跳其实就是间隔固定时间发送一个心跳包。
心跳间隔 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 进程要尽可能存活,也就是进程保活 ;
进程保活实际上是属于 Android 平台的一个话题,相信你们平常开发也遇到过,细节就不在这长篇大论了,简单的说下几个原则:
1. 优化内存,减少内存的占用,会大大的减少被 kill 的机率;
2. 多进程,将 UI 进程与 IM 进程独立出来,这样 IM 的进程负担就会小不少;
严格意义上来讲进程唤醒是属于进程保活的一个分支,这里单独列出来,是由于进程唤醒关注的是进程挂掉以后的动做。对于进程唤醒,这里也只列些原则,详细的能够去查阅相关资料。
2. Alarm定时任务,定时去检查进程是否存活。
3. JobScheduler定时任务,定时去检查进程是否存活( >5.0 )
网易云信(NeteaseYunXin)是集网易18年IM以及音视频技术打造的PaaS服务产品,来自网易核心技术架构的通讯与视频云服务,稳定易用且功能全面,致力于提供全球领先的技术能力和场景化解决方案。开发者经过集成客户端SDK和云端OPEN API,便可快速实现包含IM、音视频通话、直播、点播、互动白板、短信等功能。