对于移动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%左右。

IM推送保障及网络优化详解(二):如何做长连接加推送组合方案的更多相关文章

  1. IM推送保障及网络优化详解(一):如何实现不影响用户体验的后台保活

    对于移动APP来说,IM功能正变得越来越重要,它能够创建起人与人之间的连接.社交类产品中,用户与用户之间的沟通可以产生出更好的用户粘性. 在复杂的 Android 生态环境下,多种因素都会造成消息推送 ...

  2. Comet技术详解:基于HTTP长连接的Web端实时通信技术

    前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...

  3. P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

    1.内容概述 P2P即点对点通信,或称为对等联网,与传统的服务器客户端模式(如下图"P2P结构模型"所示)有着明显的区别,在即时通讯方案中应用广泛(比如IM应用中的实时音视频通信. ...

  4. .NET DLL 保护措施详解(二)关于性能的测试

    先说结果: 加了缓存的结果与C#原生代码差异不大了 我对三种方式进行了测试: 第一种,每次调用均动态编译 第二种,缓存编译好的对象 第三种,直接调用原生C#代码 .net dll保护系列 ------ ...

  5. PopUpWindow使用详解(二)——进阶及答疑

      相关文章:1.<PopUpWindow使用详解(一)——基本使用>2.<PopUpWindow使用详解(二)——进阶及答疑> 上篇为大家基本讲述了有关PopupWindow ...

  6. Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

    [Android布局学习系列]   1.Android 布局学习之——Layout(布局)详解一   2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)   3.And ...

  7. logback -- 配置详解 -- 二 -- <appender>

    附: logback.xml实例 logback -- 配置详解 -- 一 -- <configuration>及子节点 logback -- 配置详解 -- 二 -- <appen ...

  8. 爬虫入门之urllib库详解(二)

    爬虫入门之urllib库详解(二) 1 urllib模块 urllib模块是一个运用于URL的包 urllib.request用于访问和读取URLS urllib.error包括了所有urllib.r ...

  9. phpExcel常用方法详解【附有php导出excel加超级链接】

    phpExcel常用方法详解[附有php导出excel加超级链接] 发表于4年前(-- :) 阅读() | 评论() 0人收藏此文章, 我要收藏 赞0 http://www.codeplex.com/ ...

随机推荐

  1. Java--ConcurrentHashMap原理分析

    一.背景: 线程不安全的HashMap     因为多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap.   效率低下的H ...

  2. UVA 1347(POJ 2677) Tour(双色欧几里德旅行商问题)

    Description John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane a ...

  3. python 垃圾回收装置

    转载: https://www.cnblogs.com/pinganzi/p/6646742.html 简要描述Python的垃圾回收机制(garbage collection). 答案 这里能说的很 ...

  4. 由Maximum Gap,对话桶排序,基数排序和统计排序

    一些非比较排序 在LeetCode中有个题目叫Maximum Gap.是求一个非排序的正数数列中按顺序排列后的最大间隔.这个题用桶排序和基数排序都能够实现.以下说一下桶排序.基数排序和计数排序这三种非 ...

  5. Cocos2d-x layout (两)

    相对于对照布局 Size widgetSize = Director::getInstance()->getWinSize(); Text* alert = Text::create(" ...

  6. OpenGL(二十四) VAO、VBO和着色器使用示例

    1. 新建一个工程,新建一个头文件Shader.h,内容如下: #ifndef _SHADER_H_ #define _SHADER_H_ #include <vector> #inclu ...

  7. Android发展_备份短信

     短信备份的原理 短信备份的原理.是用内容提供者读取短信,然后保存. public class SmsBackupUtils { // 回调接口 public interface SmsBacku ...

  8. [Gevent]gevent 网络抓取问答

    我听说过gevent基于事件的异步处理功能 如何高效率,该项目已很少使用,今天是没什么学习一些简单的使用. 有正式书面一个非常好的教程 中国版的地址:http://xlambda.com/gevent ...

  9. STL 中间&lt; 超载

    相同的代码,mingw能够执行,vs不能执行. vs报告错误: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2h1Y2h1cw==/font/5a6L5 ...

  10. ESB (Enterprise Service Bus) 入门

    在本文中,ESB相关技术概念和术语.其他需要了解的入门的基础知识,并介绍了一些初步的了解ESB产品.因为它是一个新的ESB.将自己的学习内容与过程,记录下来! 愿在这里与大家分享一下,共同进步与提高! ...