Android持久化套接字连接规则

40
我一直在为Android设备使用持久套接字的自定义推送通知解决方案进行测试。我想分享我的发现并验证结果。 简单说明
该应用程序运行前台服务,与服务器建立连接,并通过积极的ping(每10秒间隔)维护该连接。如果检测到连接已死,应用程序将无限期地尝试重新连接。服务器通过双工通道发送通知。 测试1:
Pinging is done using a timer at 10 second intervals.
Server sends notification every minute.
Applications acquires wifi and wake locks.
Duration : 8 hours
Battery loss : ~14%

测试2:

Pinging is done using AlarmManager at 10 second intervals.
Server sends notification every minute.
Application acquires only a wifilock
Duration : 8 hours
Battery loss : ~7%

假设:一个传入的网络数据包会自动唤醒CPU,因此无需使用唤醒锁。使用AlarmManager进行ping操作(而不是计时器)意味着我们不需要唤醒锁。
去掉唤醒锁似乎真的有助于电池寿命。令人惊讶的是,两种解决方案中的激进ping并没有像我预期的那样影响电池寿命。(我们进行了许多其他测试,包括一个应用程序只保持wifilock并且不执行任何操作,在同一时间段内导致约4%到5%的电池损失)
由于该应用程序能够成功发送所有ping请求并接收所有传入消息,我相信我的假设是正确的。但我很想从任何专家那里得到确认。
还有一个问题: 如果该应用程序改为监听传入连接,则在这种情况下我需要保持唤醒锁,对吗?传入连接不会唤醒CPU吗?我们不会采用这种方法,只是想确认一下。
另外,请不要推荐GCM,公司政策已将其排除在外。
谢谢。

为什么在拥有套接字连接的情况下还要让移动设备发出ping信号呢?为什么不只在服务器确实有信息要传递时才发送信息,并且偶尔发送心跳以保持连接活跃呢? - Stefan de Bruijn
1
在我们的情况下,连接可能在几个交换机之间。我们需要尽快确定无效连接。因此,对于移动客户端的每个ping,服务器都必须做出响应。这可以保护我们免受静默断开的影响。 - Alex
我相信这里肯定有一个很好的问题,但是在当前的形式下我找不到它。如果你仍在寻找答案,你可以考虑编辑成一个更具针对性的问题。个人意见 :-) - Chilledrat
我们需要尽快确定无效连接。因此,对于移动客户端的每个ping,服务器都必须作出响应。我认为在传输协议下,假设是TCP,可以通过定期心跳来实现。但在Android客户端上不是这种情况吗?如果有TCP心跳,我想知道它们对电池寿命的影响有多大...? - Andrew
太棒了,伙计! - Rahul Rastogi
1个回答

16

由于此问题受到了一些关注,但没有证实,因此我现在就回答。测试已经进行了一段时间,已经创建了一个生产级别的解决方案并进行了严格测试。删除唤醒锁仍然有助于电池寿命,并且没有发现其他问题,例如丢失的ping请求或来电通知,所以这是我在上述假设上接收到的唯一验证。

额外注意事项:

  • 在用于pinging alarm的BroadcastReceiver的OnReceive方法中,如果您没有直接调用套接字(生成新线程或意图),则需要保持唤醒锁,直到ping请求完成。 Android只保持唤醒锁直到OnReceive返回,在此之后CPU可能会在完成ping之前睡眠(但很少发生)。

  • 如果通知很敏感,请使用高性能Wifi锁

  • 还有一个影响解决方案的特定于设备的问题,在这里进行了涵盖。

更新

在Android 5.1中遇到以下问题:Android Issue

更新2

需要针对Android 6.0的Doze模式进行编码:Doze Mode


我知道这是一个老问题,不过: 你是否已经获取了WakeLock来处理传入的数据包?或者换句话说,设备从网络唤醒后要保持活动状态多长时间? - JavaJens
1
是的,虽然您可以在不持有唤醒锁的情况下接收传入数据包,但在接收到传入数据时仍应创建唤醒锁。否则,在设备进入睡眠状态之前,您可能无法完成处理数据的操作。至于“多长时间”部分,这取决于设备而异。真是让人又爱又恨的碎片化问题。 - Alex
这是一个相当老的问题,但关于您的更新2中的Doze模式有什么注释吗?我发现套接字连接没有到达我正在测试我的应用程序的6.0+设备,我猜测这是因为Doze模式。尽管设置了高性能Wifi锁定,它也不响应套接字请求。是否容易避免或忽略Doze模式?白名单? - Graph
谷歌正在试图走苹果的路线,真的希望你使用他们的推送通知系统(Firebase)。幸运的是,正如你所说,你可以请求用户将你的应用程序从受到Doze模式影响的名单中删除(类似于权限)。请注意,除非你有一个很好的理由来列入白名单,否则谷歌可能会拒绝你的应用程序提交到Play商店。此外,当针对较新的API级别时,AlarmManager确实有一些限制,即使白名单也无法帮助解决。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接