Android 即时通讯开发小结(二)
《Android 即时通讯开发小结》基于IM Andriod 开发的各种常见问题,结合网易云信即时通讯技术的实践,对IM 开发做一个全面的总结。
相关推荐阅读:、
Android 即时通讯开发小结(一)
移动IM开发指南1:如何进行技术选型
移动IM开发指南2:心跳指令详解
移动IM开发指南3:如何优化登录模块
建立安全连接
安全性是 IM 软件的另一个硬需求。消息传递时如果通信数据如果被第三方截取,要能保证别人不能获取到真实内容。安全连接的过程可以参考 HTTPS 的方式,由服务器将证书下发给客户端,客户端产生一个对称的密钥,并通过服务器证书加密后交给服务器,之后的通信就全部使用这个对称的密钥来加密。当然,这里有两点需要和 HTTPS 有所区别,第一是证书的获取方式,HTTPS 中是由专门机构去验证证书合法性的,IM 的客户端肯定不会这么去做,为了防止获取证书的过程被人截获,然后篡改证书,可行的方式是直接在客户端安装包中直接把证书打进去,该证书可以随着客户端软件升级一起升级,也可以在加密连接之后通过协议升级。第二个问题是对称加密算法的选择,因为密钥的生命周期是跟随一次连接的,时间并不长,而移动 App 对于电量消耗非常敏感,因此加密算法应尽量选择较为简单的类型,例如 RC4。
心 跳
心跳可以分为 TCP 的协议层心跳和 App 的应用层心跳。一般我们都使用应用层心跳,一来便于服务器扩展(比如哪天我们可以换成 UDP 来传),二则是可以更灵活控制心跳间隔。
心跳协议仅仅是用来连接保活,其内容应当尽量精简,除了包头中必要的部分,包体的可选包头都不存在。
对于不同的网络环境,心跳可以采用不同的时间间隔。在不同网络环境下,间隔的选择可以参考微信智能心跳方案。
断线重连
客户端掉线的原因无非两种,客户端网络挂了,服务器挂了。客户端网络挂了也分两种,一种是本机就能感知到的网络连接断开,另一种是本机网络是好的,但互联网连接是不同的,对应到 Android API上,就是 NetworkInfo 的 isAvailable 和 isConnected。当然这个地方的 isConnected 不一定可靠,因为它是靠连制定服务器来确定的,那个服务器谁知道有没有问题。
掉线后,根据不同的状态需要选择不同的重连间隔。如果是本地网络出错,并不需要定时去重连,这时只需要监听网络状态,等到网络恢复后重连即可。如果网络变化非常频繁,特别是 App 处在后台运行时,对于重连也可以加上一定的频率控制,在保证一定消息实时性的同时,避免造成过多的电量消耗。
而如果掉线是因为本机网络连不通互联网,或者是服务器挂了,重连间隔的选择就非常重要了。
首先,如果程序是在前台,用户正在使用我们的 App,重连间隔应更加频繁,使得用户反馈更加及时,如果程序处于后台运行,则为了省电,可以适当延长重连间隔。
其次,随着重连次数的增加,说明服务器短时间内恢复的可能性逐渐降低,重连间隔也应随之延长(倍数增长)。但应该设置一个最大的重连间隔,当到达最大间隔时,不再增加。
第三,重连间隔的增加不应当是固定的,而应该增加一个随机退避策略。以免如果是服务器宕机造成掉线,所有客户端的重连时间点都是一样的,当服务器恢复后,同一个时间点所有客户端同时连接服务器,造成服务器不堪拥堵,再次宕机。活生生的例子请参考环信去年的宕机时间。
总结起来,重连间隔可表述如下:

多媒体数据管理
IM 系统中另一个重头戏是多媒体数据。由于移动网络比较慢,流量又贵,在移动端针对这些问题必须要做一些处理。在上传时,尽量减少上传时间,在下载时,能让用户尽快看到内容。同时,尽量节省流量,减少不必要的流量消耗。
文本消息因为比较小,可以直接通过长连接传输。但对于多媒体文件,通过长连接来传输则不合适,长连接服务器不会对大文件传输做针对性优化,大量的多媒体文件数据会直接抢占其他信令消息和文本消息的贷款资源。因此,多媒体消息会通过另外的通道,到专门的文件服务器存取。
在下载时,对于不同的网络环境,可以采用不同的预取策略。在 WiFi 环境下,由于无需考虑流量问题,在收到消息后,我们就能立即把包含的多媒体文件下载下来。而在移动网络中,则应当等到用户真正看到该多媒体消息时,才去下载。
图 片
上传时,现在手机摄像头的像素动辄上千万,一张图片随随便便就好几M,然而,通过 IM 软件传输的图片,通常对于质量要求并不会太高,如果我们直接将好几M的图片直接上传,往往费力又不讨好。在上传之前,将图片像素降低,并进行压缩,可以明显的减少上传转菊花的时间,减少用户流量消耗。如果用户确实要求图片质量,则提供一个原图选项。
如果是使用 http 上传,大文件会被分成多个数据块上传,前一个数据块传输成功后,再传输下一个。断线重传时,也是以数据块作为最小重传单元。针对不同的网络类型,数据块大小不同。在较好网络下(wifi/4g/3g),数据块可以比较大,这样可以减少交互时间,加快传输熟读,而在弱网环境,数据块应当设置的比较小,以降低传输失败概率,减少重传流量消耗。
使用 http 上传的另一个优化技术是使用 pipeline。在不使用 pipeline 时,上传一个数据块需要等到前一个数据块传输成功才行,数据通道是单工的。使用pipeline则可以将数据通道变为双工的,一个数据块传输完成后,不必等到回包,就能直接上传下一个数据包,能节省一次数据回包延时。
下载时,在消息展示区显示的通常只是一个很小的图片,这时候只需要下载对应大小的缩略图即可,无需下载原图。甚至,这里可以将比缩略图更小的图片二进制数据直接放到消息体中下发,并展示给用户一个高斯模糊后的效果图,在保证最低可用的情况下,减少用户等待时间,提高用户体验。
语 音
对于不同的网络环境,采取不同质量的语音编码算法,在较好网络时,使用高质量语音,而在弱网环境下,则使用较低质量,优先保证可用性。
为了减少用户等待时间,还可以采取边录边传的策略。由于录音时间比较长,在录制的过程中,我们就可以将录好的部分先传到服务器,等到录音完成,只需要上传最后一个数据包,并告知服务器录音完成即可,基本上可以做到录完即传完,无需等待。
语音消息没有缩略图,因此语音下载基本就只能实打实的将原始文件下载下来。
以上就是网易云信对于Android即时通讯开发的小结,欢迎各位积极提问,共同探讨。
Android 即时通讯开发小结(二)的更多相关文章
- Android 即时通讯开发小结(一)
<Android 即时通讯开发小结>基于IM Andriod 开发的各种常见问题,结合网易云信即时通讯技术的实践,对IM 开发做一个全面的总结. 相关推荐阅读:. Android 即时通讯 ...
- Protobuf实现Android Socket通讯开发教程
本节为您介绍Protobuf实现Android Socket通讯开发教程,因此,我们需要先了理一下protobuf 是什么? Protocol buffers是一种编码方法构造的一种有效而可扩展的格式 ...
- memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间
memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间 memcached vs MySQL Memory engin ...
- 提高mysql memory(heap) engine内存性能的开源补丁_XMPP Jabber即时通讯开发实践_百度空间
提高mysql memory(heap) engine内存性能的开源补丁_XMPP Jabber即时通讯开发实践_百度空间 提高mysql memory(heap) engine内存性能的开源补丁
- Android即时通讯开发之XMPP (一)初识XMPP协议和asmack
在讲XMPP和asmck之前 ,我还是先分享一些资源文档,如果你有耐心,可以直接忽略我下面所写的.下面有关XMPP的介绍大部分是摘抄网上的文档,后面我会写一些基于XMPP协议和asmck开源库的聊天室 ...
- 系列文章--C#即时通讯开发
对使用UDP协议和大规模即时通讯的思考 C#[Fox即时通讯核心] 开发记录之五 (客户端界面基窗体基本完成) C#[Fox即时通讯核心] 开发记录之四(服务端多线程异步处理数据 主程序大致结构 ...
- (Android 即时通讯) [悬赏],无论是谁发现一个漏洞奖励人民币1000元!
悬赏,无论是谁发现一个漏洞奖励人民币1000元! 3Q Android 手机版即时通讯系统正式推出,可与电脑版 地灵(http://im.yunxunmi.com) 即时通讯系统互通! 适用于: ...
- (Android 即时通讯) [悬赏],不管是谁发现一个漏洞奖励人民币1000元!
悬赏,不管是谁发现一个漏洞奖励人民币1000元! 3Q Android 手机版即时通讯系统正式推出,可与电脑版 地灵(http://im.yunxunmi.com) 即时通讯系统互通! 适用于:小米 ...
- 项目源码--Android即时通讯IM客户端
下载源码 技术要点: 1.完整精美客户端UI设计 2.自定义控件的灵活使用 3.UI控件的详细使用 4.即时通讯IM协议的实现 5.完整即时通讯IM客户端实现 6.源码详细的中文注释 ……. ...
随机推荐
- 【转】Mysql rownum 实现 及应用
Mysql rownum 实现 转自:http://blog.csdn.net/saydo/article/details/22725953 SELECT @rownum:=@rownum+1 A ...
- 使用Ocelot做网关
1首先创建一个json的配置文件,文件名随便取,我取Ocelot.json 这个配置文件有两种配置方式,第一种,手动填写 服务所在的ip和端口:第二种,用Consul进行服务发现 第一种如下: { & ...
- 还在使用vc6.0吗??vs2010吧
每个人在面对新的事物的时候,总是充满了排斥感,当vista和win7来临的时候,我们还在留恋xp,说xp是如何的好,win7是如何的不给力,当然,我们必须承认,xp是一款优秀的操作系统,这个我们无法否 ...
- WPF中,怎样将XAML代码加载为相应的对象?
原文:WPF中,怎样将XAML代码加载为相应的对象? 在前面"在WPF中,如何得到任何Object对象的XAML代码?"一文中,我介绍了使用System.Windows.Marku ...
- OpenGL(八) 显示列表
OpenGL在即时模式(Immediate Mode)下绘图时,程序中每条语句产生的图形对象被直接送进绘图流水线,在显示终端立即绘制出来.当需要在程序中多次绘制同一个复杂的图像对象时,这种即时模式会消 ...
- 使用 Capistrano 和写作 Ruby 迭代边缘部署
想边自己写ruby代码,边部署随时能够到处查看,heroku域名又不友好,速度在国内又慢.于是乎想起来capistrano,于是学起 ... capistrano 一点入门认知 https://www ...
- Convert和RelativeSource
自定义Converter 后台Converter类实现接口IValueConverter方法Convert是值->UI方法ConvertBack是UI->值初始化走Convert publ ...
- Install Oracle 12c R2 on CentOS 7 silently
准备工作 VMware 虚拟机 CentOS 7 17.08 系统安装包镜像 Oracle 12c R2 软件安装包 配置 yum 库并安装如下包 binutils-2.23.52.0.1-12.el ...
- MVC 直接或间接继承自ActionResult的类型
•ViewResult:使用View()可以指定一个页面,也可以指定传递的模型对象,如果没有指定参数则表示返回与Action同名的页面 •ContentResult:使用Content(string ...
- NetCore 上传,断点续传,可支持流上传
之前公司要做一个断点续传的业务,找了许多都没有找到合适的,都是残次不全的,终于让我遇到一个基于百度的 webuploader 的断点续传.原作者: 断点续传(上传)( https://www.some ...