工程中使用tcp长连接来和服务端进行数据传输,在IOS平台上,由于苹果的后台机制,会有以下问题:
当程序退到后台的时候,所有线程被挂起,系统会回收所有的socket资源,那么socket连接就会被关闭,因此无法再进行数据的传输。
注意:系统不会回收开启定位服务并且正在正常通信的socket资源,也不是进入后台就建立不了socket,而是进入后台断网8分钟左右及以后就申请不到新的socket资源了,并且你的建立socket资源的线程或守护线程,日志线程都会被永远挂起(和被干掉是一样的效果)。
当程序退到后台的时候,所有线程被挂起,系统会回收所有的socket资源,那么socket连接就会被关闭,因此无法再进行数据的传输。
实际测试时,开启后台定位的应用,当应用进入后台前长连接已经建立,切换到后台后一直有正常的网络,那并且有定位信号那么长连接,守护线程,日志线程都正常。
当进入的后台时正在执行connect连接时有可能永远组赛长连接线程,断网8分钟以上。
当进入后台时有网络,有正常的长连接。然后断开网络,当用户不移动位置8分钟,当连接上网络时,日志线程,守护线程,长连接线程全部(注意:应用的主线程不会被苹果系统杀死,除非出现内存的特殊情况)被ios系统杀死,无法在后台建立长连接。
咱们的应用不应该设置为voip服务,应为voip需要托管socket,最小600秒才醒来一次,让客户端有10秒的时间向服务器发送请求和处理,当然当服务器通过该通道发送消息,客户端立即被唤醒10秒。但是咱们需要10秒向服务器发送一次请求显然最小600秒的限制,并且当手机断网,这个长连接断掉也没有实时发现,所以实时通信应用不适合用voip服务。只能用普通socket。
解决方案:定位回掉函数,进入前台事件和用户UI操作触发的请求能够发现长连接线程挂掉,并且重起长连接线程。
参考文章:
iOS后台如何保持socket长连接和数据传输(http://blog.csdn.net/zhangkongzhongyun/article/details/38678137)
IOS实现Voip应用后台运行需要的几个配置项(http://blog.csdn.net/martin_liang/article/details/40818835)
1、 handler
需要说明的是,这个handler在后台执行的时候需要尽可能快的返回,因为系统只给了最多10s的时间去执行它。如果10s内没有执行完,而且没有去申请额外的执行时间,系统将会吧app挂起。
2、timeout
设置handler时,需要指定app需要的最大超时时间。IOS系统允许的最小值是600s,如果想设置个小点的值,handler的设置就会失败。系统在执行handler内容的时候,只保证超时时间到之前会执行,而不保证准确的执行时间点,系统是会根据当时的任务情况等系统条件确定一个合适的时间点,已达到延长电池寿命的目的。
所以无网络进入后台,设置voip也不能保证,应用进入后台8分钟后,守护线程,长连接线程,日志线程不被挂起。 甚至应用被杀掉。所以要在进入后台时要保证有网络,进入前台时要监控守护线程和长连接线程是否还活着。