如何在iOS的后台在React Native应用程序中运行socket.io?

问题描述:

我在iOS React Native(v0.20) app中使用socket.io。该应用跟踪我的位置,当我的位置发生变化时,它会向服务器发送消息。如果套接字连接丢失,服务器将发送一封电子邮件通知我。如何在iOS的后台在React Native应用程序中运行socket.io?

我在后台工作的位置跟踪与react-native-location,但我不能让socket.io工作。当我更改应用程序或关闭屏幕时,应用程序会跟踪我的位置,但我失去了套接字连接。

有没有办法像位置跟踪一样在后台运行socket.io?缺点是有一些本地代码,可以让我在后台维护client/server connection

我知道有一个WebSocket alternative但我看不到一种方法让它在后台运行。

UPDATE: 我翻了一番检查了我的Info.plist,它已经为react-native-location必要的背景值。我不知道它是否重要,但套接字工作和位置跟踪是在同一个组件中完成的。

enter image description here

LocationComponent.js

window.navigator.userAgent = 'react-native'; 
const io = require('socket.io-client/socket.io'); 
const socket = io(url, {jsonp: false}); 

import React, { Text, View, DeviceEventEmitter } from 'react-native'; 
import { RNLocation } from 'NativeModules'; 

export default GeolocationExample = React.createClass({ 

    componentDidMount: function() { 
    RNLocation.requestAlwaysAuthorization(); 
    RNLocation.startUpdatingLocation(); 
    RNLocation.setDistanceFilter(3.0); 
    DeviceEventEmitter.addListener('locationUpdated', locationObject => { 
     this.props.newPosition({ longitude: locationObject.coords.longitude, latitude: locationObject.coords.latitude }); 
    }); 
    }, 

    render: function() { 
    const { lastPosition, distance } = this.props; 
    socket.emit('newPos', { longitude: lastPosition.longitude, latitude: lastPosition.latitude, distance, time: Date() }); 
    return (
     <View> 
     <Text> {distance} </Text> 
     </View> 
    ); 
    } 
}); 
+1

iOS和Android上的行为类似吗?还是这是一个仅限iOS的问题? – Stavash

+0

我还没有试过Android。这是我的第一个React Native应用程序,我想专注于为iOS构建,因此我可以在手机上使用它。 – EasilyBaffled

+0

您是否找到解决方案? –

的iOS是那种过程,它允许when an app is backgrounded相当严格。

在socket.io客户端issue tracker上似乎有一些讨论。

似乎有人得到的套接字连接保持活动,如果他们将背景模式设置为audio。 YMMV

确保您在Info.plist文件的UIBackgroundModes部分设置了正确的值。 How to do this in XCode

+0

我已经在Info.plist中设置了“react-native-location”的值,正如我在问题中提到的那样,位置跟踪工作正常。我已经为问题添加了Info.plist值的图片。 – EasilyBaffled

你无法做到“正确的方式”。

编辑

从苹果公司的official documentation

实现长时间运行的任务

对于需要更多的执行时间来实现,你必须 请求特定的权限来运行他们的任务没有 的背景被暂停。在iOS中,只有特定的应用程序类型允许 在后台运行:

应用程式播放音频内容给用户,而在后台, 如音乐播放器应用程序

应用该记录的音频内容,而在 背景

应用程序,使用户在任何时间 他们的位置的通知,如导航应用

应用,支持互联网语音协议(VoIP)

应用程序需要下载和处理新的内容定期

应用程序,从外部附件

实现这些服务必须申报服务,他们 支持和使用的系统框架,以落实相关

应用程序接收定期更新这些服务的方面 。声明这些服务可让系统知道您使用的服务,但在某些情况下,实际上会阻止您的应用程序被挂起的系统框架。

这是说,有一个工作存在的技术,让您的套接字打开:

播放无声的声音,并设置背景模式为音频。查询this article了解更多关于此事的信息(这有点旧,但仍然有效)。这将允许你保持你的套接字伪造一个音频应用程序。您的info.plist应该更新以允许音频在后台运行。 UIBackgroundModes应设置为audio(检查docs以获取更多信息)

+0

我已经在后台运行位置检查。正如我所示,我已将它设置在info.plist中。难道这不应该照顾它吗? – EasilyBaffled

在你Info.plist中的图片,只允许以下三个background modes

  1. 背景取
  2. 位置更新
  3. 远程通知

    您应该允许“音频和AirPlay”模式,它似乎喜欢e“应用程序播放音频或使用Airplay播放音频/视频”。

我知道有黑客得到这个工作(即audio黑客),但有一个原因的iOS不允许在后台长时间运行的任务 - 请重新考虑你的设计,让更好的产品。

使用日志运行任务会耗尽电池电量。如果您需要数据更新,请注册以使用Apple推送服务获取推送通知(如果您直接进行此操作,或者上次处理类似问题,它是免费的)。

位置跟踪,特别是允许的后台系统服务,考虑使用本地API。

至于推送数据到服务器,你将无法(也可能不应该)与服务器保持长久的连接。

考虑收集数据并每隔一段时间向服务器上传收集到的批次 - 最好是在应用程序重新打开时,因此您不会浪费后台资源,并且让人们对电池寿命和数据消耗感到不满。

+1

我现在不关心电池的使用寿命。首先我有一个应用程序的工作示例,我宁愿解决这个问题。该应用程序的重点是分享实时更新赛车手,每个人都需要不断沟通。如果我等待太久以报告参赛者的位置,那么每个人都会失去。 – EasilyBaffled

+0

你并不担心,但苹果是当它设计的API,因此限制....也许赛车手可以保持在前台的应用程序。 – Myst

+0

虽然这在基础层面上起作用,但它远非理想。当我运行时,我打开我的音乐并关闭手机屏幕,因此将应用程序保留在前台并不适合我。 – EasilyBaffled