iOS和Android程序进入后台Socket不工作的处理方法

1,705 阅读3分钟

背景

在移动端应用使用中,iOS或者Android设备通常作为客户端和服务器通讯,当应用打开时就去连接服务器获取数据显示操作页面。由服务器确保server的稳定性,设备端做异常断连的重连。

但最近的物联网项目中,需要移动端作为server,提供服务给服务器端使用。服务器端来主动连接移动端设备。

问题

移动端由于具有可交互性,用户可能会手动退出程序,此时服务就会不稳定。

用户的异常操作通常有以下几种:

  1. 退出应用
  2. 直接退回桌面
  3. 直接锁屏

异常操作下socket的工作情况

测试使用的server由dart来实现:juejin.cn/post/717388…

平台模式操作服务情况
iOSrelease关掉断开
锁屏TCP 服务会立即断开
后台TCP 服务会工作一段时间,后断开
debug关掉断开
锁屏TCP 服务会工作一段时间,后断开
后台TCP 服务会工作一段时间,后不处理消息
Androidrelease关掉断开
锁屏TCP 服务会工作一段时间,后不处理消息
后台TCP 服务会工作一段时间,后不处理消息
debug关掉断开
锁屏TCP 服务正常工作
后台TCP 服务正常工作

分析

通过上表我们可以发现,程序在进入后台后,一段时间都不会正常操作,我们需要移动端程序在进入前台后,重启服务。 但没做测试之前我的理解是:程序在进入前台是判断一下socket有没有存在,没存在则重启一下服务。我的判断方法是:

  1. 判断socket是否为空。这种没有效果,因为程序里面写了socket断开后会先置空,后重启,正常情况下不会为空,异常情况下置空的代码不会执行
  2. 判断socket的clien是否为空。这种也没有效果,理由与1一样,异应用挂起后,置空的代码不会执行 由此,还是在程序进入前台时重启一些程序会比较稳定有效

还有一种方案是,程序进入前台后尝试给client发送一次消息,收到发送异常则重启server.这种方式可以保证程序短时间进入后台,再次进入前台不重启server

此外注意建立server和client的双向心跳机制,最大保证服务的稳定性

如何判断程序锁屏

Flutter 的 WidgetsBindingObserver可监听程序是否进入后台前台但不能判断是锁屏进入后台还是Home键进入后台。

尝试的测试方法有:

  1. 可以判断屏幕亮度,后台屏幕亮度不为0,锁屏后亮度为0。不能解决Home键后,再锁屏的操作。
  2. 通过文件的读写权限,创建一个NSFileProtectionCompleteUnlessOpen权限的文件,当app进入后台时来进行读写,读写失败表明处于锁屏,否则表明未锁屏。锁屏后权限未生效,此方法不可用
  3. iOS使用系统回调,iOS,Android未测试
- (void)applicationProtectedDataWillBecomeUnavailable:(UIApplication *)application
{
    
}
- (void)applicationProtectedDataDidBecomeAvailable:(UIApplication *)application
{
    
}