3

对于移动 APP 来说,IM 功能正变得越来越重要,它能够创建起人与人之间的连接。社交类产品中,用户与用户之间的沟通可以产生出更好的用户粘性。
在复杂的 Android 生态环境下,多种因素都会造成消息推送不能及时达到客户端。另外,不稳定的移动网络也给数据传输的速率和可靠性增加了障碍。
本文详解了网易云信 IM SDK 在应对弱网环境、移动端硬件限制以及Android复杂的生态现状时的探索与心得.如何实现不影响用户体验的后台保活,改善的长连接加推送组合方案,以及在弱网环境大数据传输的优化实践。

相关阅读推荐:

网易云信即时通讯推送保障及网络优化详解(一)如何做长连接加推送组合方案

如何做长连接

对于 IM 来说,及时的消息推送和较低的电量消耗也并非不可兼得。在传统上,每个 IM 客户端都会各自维护一条与服务器的长连接,自己的消息和信令都在这条长连接上传递,每个APP也独自去心跳,断线重连等事情。

这种模式比较简单,不同的 App 也是完全隔离的,不会互相影响。但他的缺点也非常明显,首先是做了很多重复的事情,造成了流量和电量的无谓消耗;第二是要保证所有的进程都能在后台运行很难。优化的方向也就非常明显了,那就是共享连接,现在绝大部分推送 SDK 也是这么做的。从这些 App 里面选出一个当前正在运行的,或者是被杀概率最低的 App 作为总代理,只由这个代理和服务器建立连接,一个手机上的所有其他 App 都通过这个代理中转与服务器通信。但是,IM 有一个很基本的要求在这种模式下无法得到满足:安全。所有 App 的消息都经过代理中转,代理到服务器的连接是加密的,安全的,但到了代理这里,消息都被解开了,因此代理理论上可以看到其他所有 App 的来往消息。因此,这种共享长连接的方式并不适用于 IM。

虽然共享长连接方式不合适,但仍然提供了一个优化的思路。在此基础上,有另一个可以脱敏共享连接的方式:安全长连接加推送连接模式。

每个 App 在使用和真正传递数据时,仍然独立使用自己的安全长连接。而当 App 退到后台一段时间之后,则断开长连接,然后每个 App 开启一个推送代理,并选择其中一个和网易云信的推送服务器建立连接,之后当 App 有新消息时,就通过这个推送连接传递。App 可以自己控制发出的推送消息的安全级别,可以是包含说话人和消息内容,可以只包含说话人,或者只是一条简单的有新消息到达的提醒文案。推送到达后,如果是代理 App 自己的消息,直接传递给代理 App 即可。如果是其他 App 消息,前面说到过,直接唤醒可能会失败,而且会导致无谓的电量消耗,所以这里并不直接将提醒传递给目标 App,而是由带来发出一条通知栏提醒。等用户去点击通知栏提醒后,才会把目标 App 唤醒。

现在国内的 ROM 中,华为和小米的系统本来是带有推送系统,且开放给了第三方 App 的。在这两个系统上,使用系统的推送通道明显会更加稳定,也更加节省资源。因此在 MIUI 上,从长连接到推送通道的切换流程仍然和前面的一样,只是不再使用自己的推送连接,而是将消息转发到 MIUI 的推送服务器,然后转给 MIUI 系统的推送代理,然后传递给网易云信的 App。华为的推送系统流程也是一样。不过现在华为和 MIUI 在推送实现上有一些区别,例如 MIUI 的通知栏提醒是在自己的推送代理里完成的,而华为却是将提醒通知交给 App 自己去完成的,另外,他们的通知栏提醒的管理接口也有很多区别。在 App 没有被禁用的情况下,两者都可以收到推送,而如果 App 已经被禁用了,MIUI 的通知栏提醒方式还可以将推送送达,而其他的推送方式则不能送达了。

以上就是在保障消息推送方面所能够做的所有事情了。如果以后有更多的系统开放自己的推送系统也可以选择逐步接入,以提高推送到达即时性,减少资源消耗。不过相应的,也要承受不断加入各种系统的推送 SDK,增大发布包体积的缺点。

移动通信网络的三个特点

第一个是慢,尤其是 2G,3G 网络,慢的令人发指。
第二个是断,手机跟着人不停的移动,网络也不停的在切换,从 wifi 到移动网络,从一个基站到另一个基站,从有信号到没信号,都可能导致网络中断。有些制式的网络,接打电话也会导致数据网络断开。另外,移动基站还有 NAT 超时,到一个连接上长时间空闲后,基站就会默默的将连接断开,没有任何通知。
第三个是贵,这个就不用多说。

三种长连接类型

网易云信整个通信系统中有3种类型的连接:TCP,UDP,HTTP。虽说这三个并不是同一层的协议,不过毕竟都在应用的更下层,因此这么划分也无妨。3 种类型的协议对应了不同的业务应用。TCP 主要是用户长连接,也就是普通 IM 消息和信令的传输,UDP 用于传输实时音视频数据流,而 HTTP 则主要用在音频,图片等文件的上传下载上。对于不同的业务,SDK 优化的关注点会有一些不相同。

图片描述

IM 长连接优化怎么做?

第一个是协议的选择。前面说,长连接的使用量是最大,选择一个合适的协议至关重要。如果是刚开始接触IM 开发,一般会选择一些开源的协议,比如 XMPP,SIP 等。这是 XMPP 协议的一个请求样例,可以看到是一段 XML 格式的文本数据。

图片描述

这是基于 SIP 的 SIMPLE 协议的一个请求样例,可以看到是一段类似 HTTP 协议的文本数据。这些协议的优势在于开源,有成熟的解决方案可以使用,扩展性好,甚至还可以和其他系统互联互通,协议的可读性也非常好。但是在普遍比较臃肿,冗余字段很多,在昂贵的移动网络里面用起来会比较浪费。网易云信采用的是私有的二进制协议,这是一个请求的数据样例,这里是把二进制数据转为了 16 进制显示出来,每个字节这里显示为两个字符。可以看到二进制协议的特点在于完全失去了可读性,但是,却带来极高的表达效率,相对于文本协议,可以节省非常多的数据流量。

另一个例子是登录的优化。由于移动网络经常断开,所以登录常常是心跳之外交互最多的协议了。使用量越大,优化就越有意义。一般而言,登录会经过这么几步。

图片描述

  • 第一步是 LBS。

这里的 LBS 不是经常说的基于地址位置的服务,在不同的厂商可能也有不同的叫法,反正作用都是获取服务器的IP地址。像云信这种需要提供全球服务的系统,在世界各地都要部署服务器,用户登录时,肯定要选择一台最优的服务器接入服务。通过lbs,客户端可以获取离自己最近,连通性最好的服务器连接机IP地址,服务器也可以据此做负载均衡。

  • 拿到服务器连接机IP后,客户端就去连接该服务器。

连接成功,需要有一次握手。这个握手不是TCP的三次握手,而是为了建立安全连接,同服务器协商加密算法和加密密钥。
然后就发送登录请求,这里会带上用户认证信息,本机设备信息等数据。
登录成功之后,就是同步数据,包括离线消息,用户信息,群组信息等。一般而言,这里不会去做全量同步,而是采用基于时间戳的增量同步。

在移动网络上,每一次交互都需要比较长的时间,同时,每一次网络请求电量消耗也是很大的。所以,优化的方向就是尽量减少交互次数,而方法则是合并请求,并行操作以及省略请求。
LBS 和连接这两个步骤是可以并行完成的。如果前面已经获取过 LBS,这里可以有之前的缓存地址,如果没有,可以先连一个默认地址。

  • 其次是握手和登录也可以并行操作。

在握手包中,就可以把加密后的登录包直接带上去了。如果是断线重连,网易还可以简化登录,直接带上上一次登录的会话 ID,一来减少服务器鉴权压力,二则可以直接带回在断线期间是否有未读消息等数据,如果没有,则能直接将同步这一步省略掉。如果有,同步也可以只做部分同步,只去拉去离线消息即可。等到 App 切换到前台,才去同步其他的信息。
通过这些优化,登录时间可以降为原来的 1/2 到 1/3,登录的流量消耗也可以节省 30% 左右。


随着音频处理和压缩技术的不断发展,效果更好、适用范围更广、性能更高的算法和新的技术必将不断涌现,如果你有好的技术或者分享,欢迎关注网易 MC 官方博客以及微信公众号:**

关注更多技术干货内容:网易云信博客
欢迎关注网易云信 GitHub
欢迎关注网易云信官网

网易数智
619 声望140 粉丝

欢迎关注网易云信 GitHub: