Подтвердить что ты не робот

Как запустить socket.io в фоновом режиме на iOS в приложении React Native?

Я использую socket.io в iOS React Native(v0.20) app. Приложение отслеживает мое местоположение, и когда моя позиция изменяется, он отправляет сообщение на сервер. Если соединение сокета потеряно, сервер отправляет электронное письмо, чтобы уведомить меня.

У меня есть отслеживание местоположения, работающее в фоновом режиме с react-native-location, но я не могу заставить socket.io работать. Когда я меняю приложения или выключаю экран, приложение отслеживает мое местоположение, но я теряю соединение сокета.

Есть ли способ запустить socket.io в фоновом режиме, например, отслеживание местоположения? Коротко это есть некоторый собственный код, который позволит мне поддерживать client/server connection в фоновом режиме?

Я знаю, что есть альтернатива WebSocket, но я не вижу способа заставить его работать в фоновом режиме.

UPDATE: Я удвоил проверил мой Info.plist, он имеет необходимые значения фона, установленные уже для react-native-location. Я не знаю, важно ли это, но работа сокетов и отслеживание местоположения выполняются в одном компоненте.

введите описание изображения здесь

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>
    );
  }
});
4b9b3361

Ответ 1

Вы не можете сделать это "правильно".

Edit

От Apple официальная документация:

Реализация задач с длительным запуском

Для задач, требующих большего времени выполнения, вы должны запросить конкретные разрешения для запуска их в фоновом режиме без их приостановление. В iOS разрешены только определенные типы приложений запустите в фоновом режиме:

Приложения, которые воспроизводят звуковой контент пользователю в фоновом режиме, например, приложение для музыкального проигрывателя

Приложения, которые записывают аудиоконтент во время фон

Приложения, которые сообщают пользователям об их местоположении вообще таких как навигационное приложение

Приложения, поддерживающие передачу голоса по интернет-протоколу (VoIP)

Приложения, которые необходимо регулярно загружать и обрабатывать новый контент

Приложения, регулярно получающие обновления от внешних аксессуаров

Приложения, реализующие эти службы, должны объявлять службы, которые они поддержки и использования системных рамок для реализации соответствующих аспектов эти услуги. Объявление служб позволяет системе знать, какие которые вы используете, но в некоторых случаях это системные на самом деле запретить приостановление вашего приложения.

Говоря об этом, существует работающий метод, чтобы держать ваш сокет открытым:

Воспроизводите звук без звука и установите фоновый режим на звук. эту статью для получения дополнительной информации по этому вопросу (она немного устарела, но все еще действительна). Это позволит вам держать ваш сокет открытым притвором аудио приложения. Ваш info.plist должен быть обновлен, чтобы звук работал в фоновом режиме. UIBackgroundModes следует установить в audio (подробнее см. docs)

Ответ 2

iOS довольно ограничительно относится к тем процессам, которые позволяет при создании фонового файла.

Похоже, что об этом обсуждается на сервере socket.io отслеживание проблем.

Кажется, кто-то получил соединение сокета, чтобы оставаться активным, если установить фоновый режим на audio. YMMV

Убедитесь, что вы устанавливаете правильные значения в разделе UIBackgroundModes файла Info.plist. Как это сделать в XCode

Ответ 3

Я знаю, что есть хаки, чтобы сделать это (т.е. audio hack), но есть причина, по которой iOS не позволяет выполнять длительные задачи в фоновом режиме - переосмыслите свой дизайн, чтобы обеспечить лучший продукт.

Использование задач, выполняемых журналом, приведет к истощению батареи. Если вам нужны обновления данных, зарегистрируйтесь, чтобы получать push-уведомления с помощью Apple push-сервиса (это бесплатно, если вы делаете это напрямую, или это был последний раз, когда я имел дело с аналогичной проблемой).

Отслеживание местоположений, в частности, является разрешенным фоновым системным сервисом, рассмотрите возможность использования встроенного API для этого.

Что касается передачи данных на сервер, вы не сможете (и, вероятно, не должны) поддерживать длительное соединение с сервером.

Рассматривайте сбор данных и выгрузку на сервер собранной партии каждый раз в то время - желательно, когда приложение снова открывается, поэтому вы не тратите ресурсы на задний план и не расстраиваетесь над временем автономной работы и потреблением их данных.

Ответ 4

В вашей картинке Info.plist он позволяет использовать только три следующих фоновых режима:

  • Фоновая выборка
  • Обновления местоположения
  • Удаленные уведомления

    Вы должны разрешить режим "Аудио и AirPlay", и кажется, что "приложение воспроизводит аудио или передает аудио/видео с помощью Airplay".