默认
打赏 发表评论 23
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
阅读(259378) | 评论(23 收藏23 淘帖2 7
微信扫一扫关注!

前言


最近研究Android推送的实现, 研究了两天一夜, 有了一点收获, 写下来既为了分享, 也为了吐槽. 需要说明的是有些东西偏底层硬件和通信行业, 我对这些一窍不通, 只能说说自己的理解.

为什么要研究Android推送技术? 主要还是毕业设计要做一个即时通信app, 我是不喜欢做什么社交app的, 也就象牙塔里的人想得出来, 说实话有这功夫还不如钻研一个小技术点, 把一个点研究透彻, 比搞个大而全, 还无用的东西好得多, 不过谁叫咱们是普通人, 没得选呢。

更多资料


更多推送技术文章:http://www.52im.net/forum.php?mod=collection&action=view&ctid=11
更多心跳保活资料:http://www.52im.net/forum.php?mod=collection&action=view&ctid=17

Android推送服务的几种实现方式


现实生活中, 推送服务就像订杂志一样, 只要留下你的地址, 杂志就能如期送到你手里, 可以认为每个人都有唯一的一个地址, 但在目前的网络上, 这是办不到的, 因为不是每个人都有一个唯一的地址, 服务器想要给我们推送一条消息, 必须知道我们的地址, 但服务器不知道我们在哪.

说到推送服务, 我所知道的实现方案有如下几种。(更多有关推送的技术资料请见:http://www.52im.net/forum.php?mod=collection&action=view&ctid=11

1轮询


客户端定期询问服务器有没有新的消息, 这样服务器不用管客户端的地址是什么, 客户端来问, 直接告诉它就行.

这种方案最简单, 对于一些不追求实时性的客户端来说, 很适合, 只需要把时间间隔设定成几个小时取一次, 就能很方便的解决问题.

但对于即时通讯产品来说, 这种方案完全不能用. 假设即时通讯软件在网络畅通的情况下发送的消息要求对方10s内就能收到, 如果用轮询, 那么客户端要每隔5s连一次服务器, 如果在移动端, 手机的电量和流量很快就会被消耗殆尽。

2SMS通知


这种方案在移动端是有可能的, 让客户端拦截手机短信, 服务器在有新消息时给用户的手机号发一条特殊的短信, 客户端拦截短信后发现是正常短信就放行, 如果是特殊短信就连接服务器取消息.

运营商不会配合, 用户也不会放心, 这方案普通公司玩不起.

3长连接


这大概是目前情况下最佳的方案了, 客户端主动和服务器建立TCP长连接之后, 客户端定期向服务器发送心跳包, 有消息的时候, 服务器直接通过这个已经建立好的TCP连接通知客户端.

4XMPP、MQTT等不算推送技术


在网上搜索资料的时候, 经常看见XMPP协议实现的Android推送和MQTT协议实现的Android推送, 我个人觉得这两种说法都怪怪的, XMPP和MQTT二者都是协议, 尽管我不清楚严格来讲这俩协议工作在哪一层, 但是绝对是在传输层之上的, 姑且认为他俩在TCP/IP四层模型的应用层吧, 闭口不提传输层的实现, 而是扯应用层, 这种说法真是令我费解, 所以我个人认为XMPP, MQTT等等不算推送技术.

关于为什么TCP/IP是四层模型, 感谢评论区指出, 对应的是 应用层, 传输层, 网络层, 网络接口层, 也有说法把网络接口层分成两层, 这样就有了五层, 因为TCP/IP是事实上的模型, 所以说法不一很正常, 主流说法是四层.


关于这个XMPP, 我想很多人都是参考Openfire和Smack那套东西, 我一年前尝试用aSmack和Openfire做IM, 不过那个时候什么都不懂, 做的东西很烂, 唯一懂的就是Openfire这东西相当老了, 我看有一些开源的推送解决方案都是在这套东西的基础上改的, 想想这工作量, 挺可怕的.

(有关TCP/IP的更多资料请参考TCP/IP详解》,TCP/IP协议族关系图请见《计算机网络通讯协议关系图(中文珍藏版)》)

细说TCP长连接与心跳


长连接方案乍一听怪怪的, 什么是长连接? 定时发送心跳, 这和轮询有什么区别? 心跳是干什么的? 同样是定期和服务器沟通, 为什么长连接就比轮询更加优秀? 手机休眠了TCP连接不会断掉吗?

这是我在刚开始研究推送技术的时候的问题, 虽然有些还是没有很准确的答案, 但了解的大概可以分享一下, 有什么错误欢迎指出.

1什么是长连接


先说短连接, 短连接是通讯双方有数据交互时就建立一个连接, 数据发送完成后,则断开此连接。

Android端消息推送总结:实现原理、心跳保活、遇到的问题等_1.png

长连接就是大家建立连接之后, 不主动断开. 双方互相发送数据, 发完了也不主动断开连接, 之后有需要发送的数据就继续通过这个连接发送.

TCP连接在默认的情况下就是所谓的长连接, 也就是说连接双方都不主动关闭连接, 这个连接就应该一直存在.

但是网络中的情况是复杂的, 这个连接可能会被切断. 比如客户端到服务器的链路因为故障断了, 或者服务器宕机了, 或者是你家网线被人剪了, 这些都是一些莫名其妙的导致连接被切断的因素, 还有几种比较特殊的。

2NAT超时


因为IPv4地址不足, 或者我们想通过无线路由器上网, 我们的设备可能会处在一个NAT设备的后面, 生活中最常见的NAT设备是家用路由器.

NAT设备会在IP封包通过设备时修改源/目的IP地址. 对于家用路由器来说, 使用的是网络地址端口转换(NAPT), 它不仅改IP, 还修改TCP和UDP协议的端口号, 这样就能让内网中的设备共用同一个外网IP. 举个例子, NAPT维护一个类似下表的NAT表:

Android端消息推送总结:实现原理、心跳保活、遇到的问题等_QQ20160530-0.png

NAT设备会根据NAT表对出去和进来的数据做修改, 比如将192.168.0.3:8888发出去的封包改成120.132.92.21:9202, 外部就认为他们是在和120.132.92.21:9202通信. 同时NAT设备会将120.132.92.21:9202收到的封包的IP和端口改成192.168.0.3:8888, 再发给内网的主机, 这样内部和外部就能双向通信了, 但如果其中192.168.0.3:8888 == 120.132.92.21:9202这一映射因为某些原因被NAT设备淘汰了, 那么外部设备就无法直接与192.168.0.3:8888通信了。

我们的设备经常是处在NAT设备的后面, 比如在大学里的校园网, 查一下自己分配到的IP, 其实是内网IP, 表明我们在NAT设备后面, 如果我们在寝室再接个路由器, 那么我们发出的数据包会多经过一次NAT.

国内移动无线网络运营商在链路上一段时间内没有数据通讯后, 会淘汰NAT表中的对应项, 造成链路中断。

(有关NAT端口老化的技术资料详见:《NAT详解:基本原理、穿越技术(P2P打洞)、端口老化等》)

3网络状态切换


手机网络和WIFI网络切换, 网络断开和连上等情况, 也会使长连接断开. 这里原因可能比较多, 但结果无非就是IP变了, 或者被系统通知连接断了.

4DHCP的租期


目前测试发现安卓系统对DHCP的处理有Bug, DHCP租期到了不会主动续约并且会继续使用过期IP, 这个问题会造成TCP长连接偶然的断连。


引自《移动端IM实践:实现Android版微信的智能心跳机制》。

心跳包的作用


网上很多文章介绍长连接的时候都说:

  • 因为是长连接, 所以需要定期发送心跳包;
  • 心跳包是用来通知服务器客户端当前状态。

提出这些说法的人其实自己也是一知半解. 这些说法其实都对, 但是没有答到点上. 就好像别人问: "你为什么要去食堂"? 这人回答: "检查自己还能不能找到食堂". 这个答案说不上错了, 但是其实这人是去食堂吃饭的, 证明自己认得路只是个附赠品。

明确一点, TCP长连接本质上不需要心跳包来维持, 大家可以试一试, 让两台电脑连上同一个wifi, 然后让其中一台做服务器, 另一台用一个普通的没有设置KeepAlive的Socket连上服务器, 只要两台电脑别断网, 路由器也别断电, DHCP正常续租, 就这么放着, 过几个小时再用其中一台电脑通过之前建立的TCP连接给另一台发消息, 另一台肯定能收到。

那为什么要有心跳包呢? 其实主要是为了防止上面提到的NAT超时, 既然一些NAT设备判断是否淘汰NAT映射的依据是一定时间没有数据, 那么客户端就主动发一个数据。

当然, 如果仅仅是为了防止NAT超时, 可以让服务器来发送心跳包给客户端, 不过这样做有个弊病就是, 万一连接断了, 服务器就再也联系不上客户端了. 所以心跳包必须由客户端发送, 客户端发现连接断了, 还可以尝试重连服务器。

所以心跳包的主要作用是防止NAT超时, 其次是探测连接是否断开。

链路断开, 没有写操作的TCP连接是感知不到的, 除非这个时候发送数据给服务器, 造成写超时, 否则TCP连接不会知道断开了. 主动kill掉一方的进程, 另一方会关闭TCP连接, 是系统代进程给服务器发的FIN. TCP连接就是这样, 只有明确的收到对方发来的关闭连接的消息(收到RST也会关闭, 大家都懂), 或者自己意识到发生了写超时, 否则它认为连接还存在。

(有关TCP为何还需要心跳保活的好文,请参见:基于TCP协议的移动端IM仍然需要心跳保活机制

心跳包的时间间隔


既然心跳包的主要作用是防止NAT超时, 那么这个间隔就大有文章了。

发送心跳包势必要先唤醒设备, 然后才能发送, 如果唤醒设备过于频繁, 或者直接导致设备无法休眠, 会大量消耗电量, 而且移动网络下进行网络通信, 比在wifi下耗电得多. 所以这个心跳包的时间间隔应该尽量的长, 最理想的情况就是根本没有NAT超时, 比如刚才我说的两台在同一个wifi下的电脑, 完全不需要心跳包. 这也就是网上常说的长连接, 慢心跳。

现实是残酷的, 根据网上的一些说法, 中移动2/3G下, NAT超时时间为5分钟, 中国电信3G则大于28分钟, 理想的情况下, 客户端应当以略小于NAT超时时间的间隔来发送心跳包。

wifi下, NAT超时时间都会比较长, 据说宽带的网关一般没有空闲释放机制, GCM有些时候在wifi下的心跳比在移动网络下的心跳要快, 可能是因为wifi下联网通信耗费的电量比移动网络下小。

关于如何让心跳间隔逼近NAT超时的间隔, 同时自动适应NAT超时间隔的变化, 可以参看《移动端IM实践:实现Android版微信的智能心跳机制》。

服务器如何处理心跳包


如果客户端心跳间隔是固定的, 那么服务器在连接闲置超过这个时间还没收到心跳时, 可以认为对方掉线, 关闭连接. 如果客户端心跳会动态改变, 如上节提到的微信心跳方案, 应当设置一个最大值, 超过这个最大值才认为对方掉线. 还有一种情况就是服务器通过TCP连接主动给客户端发消息出现写超时, 可以直接认为对方掉线.

这个就需要具体业务具体分析了, 也许还有更优的策略, 这里就不写了。

(有关心跳策略的好文请参见:《微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)》、《移动端IM实践:实现Android版微信的智能心跳机制》)

心跳包和轮询的区别


心跳包和轮询看起来类似, 都是客户端主动联系服务器, 但是区别很大:

  • 轮询是为了获取数据, 而心跳是为了保活TCP连接。
  • 轮询得越频繁, 获取数据就越及时, 心跳的频繁与否和数据是否及时没有直接关系
  • 轮询比心跳能耗更高, 因为一次轮询需要经过TCP三次握手, 四次挥手, 单次心跳不需要建立和拆除TCP连接.

TCP唤醒Android


这部分内容我只知道结论, 不知道具体的知识。

大家有没有想过, 手机的短信功能和微信的功能差不多, 为什么微信会比短信耗电这么多? 当然不是因为短信一条0.1元. 手机短信是通过什么获取推送的呢?
下面这段出处不明的话也许可以给大家启示:

首先Android手机有两个处理器, 一个叫Application Processor(AP), 一个叫Baseband Processor(BP). AP是ARM架构的处理器,用于运行Android系统; BP用于运行实时操作系统(RTOS), 通讯协议栈运行于BP的RTOS之上. 非通话时间, BP的能耗基本上在5mA左右,而AP只要处于非休眠状态, 能耗至少在50mA以上, 执行图形运算时会更高. 另外LCD工作时功耗在100mA左右, WIFI也在100mA左右. 一般手机待机时, AP, LCD, WIFI均进入休眠状态, 这时Android中应用程序的代码也会停止执行.

Android为了确保应用程序中关键代码的正确执行, 提供了Wake Lock的API, 使得应用程序有权限通过代码阻止AP进入休眠状态. 但如果不领会Android设计者的意图而滥用Wake Lock API, 为了自身程序在后台的正常工作而长时间阻止AP进入休眠状态, 就会成为待机电池杀手.

完全没必要担心AP休眠会导致收不到消息推送. 通讯协议栈运行于BP,一旦收到数据包, BP会将AP唤醒, 唤醒的时间足够AP执行代码完成对收到的数据包的处理过程. 其它的如Connectivity事件触发时AP同样会被唤醒. 那么唯一的问题就是程序如何执行向服务器发送心跳包的逻辑. 你显然不能靠AP来做心跳计时. Android提供的Alarm Manager就是来解决这个问题的. Alarm应该是BP计时(或其它某个带石英钟的芯片,不太确定,但绝对不是AP), 触发时唤醒AP执行程序代码. 那么Wake Lock API有啥用呢? 比如心跳包从请求到应答, 比如断线重连重新登陆这些关键逻辑的执行过程, 就需要Wake Lock来保护. 而一旦一个关键逻辑执行成功, 就应该立即释放掉Wake Lock了. 两次心跳请求间隔5到10分钟, 基本不会怎么耗电. 除非网络不稳定. 频繁断线重连, 那种情况办法不多.

网上有说使用AlarmManager,因为AlarmManager 是Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。


上面所说的通信协议, 我猜应该是无线资源控制协议(Radio Resource Control), RRC应该工作在OSI参考模型中的第三层网络层, 而TCP, UDP工作在第四层传输层, 上文说的BP, 应该就是手机中的基带, 也有叫Radio的, 我有点搞不清楚Radio怎么翻译. Google在Optimizing Downloads for Efficient Network Access中提到了一个叫Radio State Machine的东西, 我翻译成无线电波状态机, 也不知道正确的翻译是什么.

移动网络下, 每一个TCP连接底层都应该是有RRC连接, 而RRC连接会唤醒基带, 基带会唤醒CPU处理TCP数据, 这是我个人的理解。

至于wifi下如何工作, 我暂时没有找到资料。

上面说了这么多, 其实意思就是TCP数据包能唤醒手机. 至于UDP, 我不确定。

而推送中最重要的部分就是让手机尽量休眠, 只有在服务器需要它处理数据时才唤醒它, 这正好符合我们的要求。

(相关技术可参见文章:《移动端实时消息推送技术浅析》)

最新补充:鉴于高版本Android对于后台网络进程的滥杀问题,下面这几篇文章可供你借鉴:
应用保活终极总结(一):Android6.0以下的双进程守护保活实践
应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)
应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)

移动网络下的电量消耗


Google在Optimizing Downloads for Efficient Network Access中提到了一个叫Radio State Machine的东西.

Android端消息推送总结:实现原理、心跳保活、遇到的问题等_2.png

说的应该就是基带的工作状态, 在Radio Standby下几乎不耗电, 但是一旦有需要处理的事情, 比如手机里某个app要访问网络(从上一节可以推测: 收到RRC指令也会导致唤醒), 就会进入到Radio Full Power中, 由Standby转为Full Power这一唤醒过程很耗电, Full Power下基带空闲后5s进入Radio Low Power, 如果又空闲12s才进入Standby. 主要的意思就是不要频繁的唤醒基带去请求网络, 因为只要一唤醒, 就至少会让基带在Full Power下工作5s, 在Low Power下工作12s, 而且唤醒过程很耗电. 所以在移动网络下, 心跳需要尽量的慢才好, 不过以当前这种情况, 想慢下来几乎不可能.

不过这也带来另外一个问题, 假如手机里有10个应用, 每个应用都发送心跳包, 每个应用的服务器都可能唤醒手机, 那手机还休不休眠了?

实际实践中遇到的问题总结


了解完了我就开始动手做demo, 服务器使用Apache的Mina, 客户端也用这个。

1Mina


这个框架挺好用, 就是遇到些很奇怪的事情, 我两天前看的, 所以也可能是我自己的问题.

一个是Android端发一个汉字给服务器, 服务器filter崩溃, 发超过一个汉字, 客户端filter崩溃, 写个IoFilter做一下编解码就好了. 另外User Guide里面的代码也有错误. 第二个是IoSessionConfig的写超时设置了完全不起作用.

2小米手机的神奇Socket


后来又发现客户端只要在后台超过一定时间, 对socket的写操作就会变得非常诡异, 表现为socket把数据吞了, 告知应用数据已经被对方接收, 但是服务器什么都没收到, 而且服务器发送的消息客户端也收不到. 只要让app进到前台, 之前消失的数据会一股脑发给服务器, 客户端会收到服务器重传的消息.

我开始还以为是Android的休眠机制把wifi断了, 我把各种WifiLock, WakeLock都持有了, 还是出这种情况. 后来无意间发现小米针对每个app都有个后台运行时允许联网的开关, 我把它打开了, 果然好了一阵子, 后来又开始重复之前的情况, 我还以为是Mina的IO线程被kill了还是怎么, 用DDMS看了线程信息没问题. 不放心, 又用纯Socket实现了客户端, 还是有问题, 再在之前的基础上加上1分钟的心跳, 还是有问题。

3小米手机的神奇bug


这次真是我运气好, 我又看了一眼后台运行时允许联网的开关, 发现demo app的这个开关刚刚还被我打开了, 这下又关上了, 我怀疑是小米的这个功能有bug, 我是记得有小米员工提到这东西有服务器下发白名单的, 我认为是服务器下发数据把我的改动给覆盖了, 我把几个app的后台联网关了, 重启手机之后, 他们又开了。

最后我改了个10s的心跳间隔, 在心跳的时候, 把后台允许联网关掉, 复现了那个神奇的socket行为, 大概确定是MIUI的bug。

睡了一觉起来, MIUI的工程师联系了我, 确认是bug. 顺便提醒一下用小米做测试机的开发者和用户, 这个bug的临时解决方案是: 用神隐模式里的自定义配置, 把自己想改的设置好就行。

想起一年前什么都不懂就跑去小米面试就好笑, 我这水平完全就是坑人, 然而没想到这次被小米坑了。

4关于休眠的几个坑点


首先看一下Android Powermanager Class Overview,对Android的几种不同的休眠模式有个大致了解。

如果不进行特别的设置,Android会在一定时间后屏幕变暗,在屏幕变暗后一定时间内,约几分钟,CPU也会休眠,大多数的程序都会停止运行,从而节省电量。但你可以在代码中通过对Powmanager API的调用来设置不同的休眠模式。

Flag Value CPU Screen Keyboard
PARTIAL_WAKE_LOCK On* Off Off
SCREEN_DIM_WAKE_LOCK On Dim Off
SCREEN_BRIGHT_WAKE_LOCK On Bright Off
FULL_WAKE_LOCK On Bright Bright


如上表,最高等级的休眠是屏幕,键盘等,cpu都全部休眠。可以设置不同的模式,让其产生不同的休眠,比如让cpu保持运行。设置代码如下:
PowerManagerpm =(PowerManager)getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLockwl =pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,"My Tag");
wl.acquire();
..screen will stay on during thissection..
wl.release();

我曾经遇到的几个坑点及解决:

  • 向服务器轮询的代码不执行:
    曾经做一个应用,利用Timer和TimerTask,来设置对服务器进行定时的轮询,但是发现机器在某段时间后,轮询就不再进行了。查了很久才发 现是休眠造成的。后来解决的办法是,利用系统的AlarmService来执行轮询。因为虽然系统让机器休眠,节省电量,但并不是完全的关机,系统有一部 分优先级很高的程序还是在执行的,比如闹钟,利用AlarmService可以定时启动自己的程序,让cpu启动,执行完毕再休眠。
  • 后台长连接断开:
    最近遇到的问题。利用Socket长连接实现QQ类似的聊天功能,发现在屏幕熄灭一段时间后,Socket就被断开。屏幕开启的时候需进行重连,但 每次看Log的时候又发现网络是链接的,后来才发现是cpu休眠导致链接被断开,当你插上数据线看log的时候,网络cpu恢复,一看网络确实是链接的, 坑。最后使用了PARTIAL_WAKE_LOCK,保持CPU不休眠。
  • 调试时是不会休眠的:
    让我非常郁闷的是,在调试2的时候,就发现,有时Socket会断开,有时不会断开,后来才搞明白,因为我有时是插着数据线进行调试,有时拔掉数据线,这 时Android的休眠状态是不一样的。而且不同的机器也有不同的表现,比如有的机器,插着数据线就会充电,有的不会,有的机器的设置的充电时屏幕不变暗 等等,把自己都搞晕了。其实搞明白这个休眠机制,一切都好说了。

附录:有关IM/推送的进程保活/网络保活方面的文章汇总


应用保活终极总结(一):Android6.0以下的双进程守护保活实践
应用保活终极总结(二):Android6.0及以上的保活实践(进程防杀篇)
应用保活终极总结(三):Android6.0及以上的保活实践(被杀复活篇)
Android进程保活详解:一篇文章解决你的所有疑问
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
深入的聊聊Android消息推送这件小事
为何基于TCP协议的移动端IM仍然需要心跳保活机制?
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
Android P正式版即将到来:后台应用保活、消息推送的真正噩梦
全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)
一文读懂即时通讯应用中的网络心跳包机制:作用、原理、实现思路等
融云技术分享:融云安卓端IM产品的网络链路保活技术实践
正确理解IM长连接的心跳及重连机制,并动手实现(有完整IM源码)
2020年了,Android后台保活还有戏吗?看我如何优雅的实现!
史上最强Android保活思路:深入剖析腾讯TIM的进程永生技术
Android进程永生技术终极揭密:进程被杀底层原理、APP对抗被杀技巧
>> 更多同类文章 ……

(原文链接:http://www.jianshu.com/p/584707554ed7

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:扫盲贴:认识MQTT通信协议下一篇:iOS的推送服务APNs详解:设计思路、技术原理及缺陷等

本帖已收录至以下技术专辑

推荐方案
评论 23
写的不错!
有前途,作者是块搞技术的料
签名: 国庆长假还没有缓过来,请让我静一静,产品狗死远点...
写的不错
我用AlarmManager和WakeLock每隔5分钟向服务器发送心跳,在红米Note2上CPU休眠以后用WakeLock无法唤醒CPU,心跳发送不出去
引用:花满楼 发表于 2016-08-30 10:53
我用AlarmManager和WakeLock每隔5分钟向服务器发送心跳,在红米Note2上CPU休眠以后用WakeLock无法唤醒CPU, ...

小米的神隐模式,看看这篇吧:http://www.52im.net/thread-354-1-1.html
进不了小米的白名单,怕是没招
引用:JackJiang 发表于 2016-08-30 11:55
小米的神隐模式,看看这篇吧:http://www.52im.net/thread-354-1-1.html
进不了小米的白名单,怕是没招

居然还有这个东西,我测试了一下发现关闭掉那个省电模式,直接用Timer定时器就可以定时发送了
引用:花满楼 发表于 2016-08-30 15:17
居然还有这个东西,我测试了一下发现关闭掉那个省电模式,直接用Timer定时器就可以定时发送了

学习了,谢谢分享!
签名: 该会员没有填写今日想说内容.
关于长连接中心跳包的意义,这才是正解,因此必须要注册会员,参与点赞!
引用:qq497495160 发表于 2017-06-15 15:35
关于长连接中心跳包的意义,这才是正解,因此必须要注册会员,参与点赞!

看看
签名:
多谢分享
签名: 继续。。。。。
谢谢分享
签名: 心情好
很可以   努力ing
签名: 刚来,知识都是我的菜!
神秘人  发表于 5 年前
神秘人  发表于 5 年前
神秘人  发表于 5 年前
神秘人  发表于 5 年前
后台后心跳无法连接用socket io,mqtt都不行怎么办 service还活着,解锁后立刻连上了
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部