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

Я создаю конкурирующее приложение в реальном времени для мобильных устройств для фитнес-оборудования (через BLE). Мобильные устройства могут получать команду с сервера в разное время из-за задержки. Я пытаюсь добиться того, чтобы все устройства синхронизировались с сервером и одновременно выполняли команду запуска гонки. Таким образом, пользователи, которые не обязательно находятся рядом друг с другом, получат как можно больше опыта, близкого к реальному времени, и начнут соревноваться в самый близкий момент. На данный момент я использую WebSockets для публикации команд в своем мобильном приложении, но, скажем, устройство A получит их в течение 20 мс, а устройство B получит их в течение 150 мс. Как бы это ни было мгновением ока, это очень заметно на фитнес-оборудовании. Как я могу архитектурно создать приложение, которое, например, будет выполнять команду на всех устройствах в 13:00 UTC? Проблема здесь в том, что мобильные устройства могут иметь разное время, поэтому я хочу, чтобы мое мобильное приложение синхронизировалось со временем сервера, и если я скажу выполнить команду в 13:00 по времени сервера UTC, я знаю, что все мобильные устройства добьются этого.

Текущая архитектура:

расписание или команда, вызываемая вручную -> SignalR уведомляет все подключенные устройства -> запуск устройств

Возможная архитектура:

запланированная или вызываемая вручную команда позволяет устройствам знать точное время для запуска команды -› SignalR (WebSockets или какая-либо другая технология) уведомляет подключенное устройство о синхронизации времени мобильного приложения с сервером и временем выполнения команды -› Команда выполняется почти в реальном времени во многих устройства

Как синхронизировать время? С помощью НТП? Какую архитектуру вы предлагаете для этого сценария?

Я видел много подобных приложений, но я пытаюсь понять архитектуру. Технологии, на мой взгляд, не имеют значения, я не могу контролировать время выполнения BLE на фитнес-оборудовании, но они быстрые. Если это поможет, я использую SignalR для WebSockets (.NET Core 3.x на C#), мобильное приложение работает на Flutter/Dart.


person zuboje    schedule 04.02.2021    source источник


Ответы (1)


Для синхронизации времени вы можете использовать метод toUtc.

Возвращает это значение DateTime в часовом поясе UTC.

А затем, чтобы запустить его в одно и то же время на всех устройствах, используйте Таймер

Создает новый таймер. Функция обратного вызова вызывается по истечении заданного времени.

Рабочий пример ниже:

import 'dart:core';

DateTime startTime = DateTime.utc(2021, 2, 16, 15, 0); // you feed the startTime from your server using websocket.

void checkForStart(Timer timer) {
  print(startTime);
  timer?.cancel();
  while (true) {
    print('Run Forest!');
    // [... do your app things]
  }
}

...

 initState() {
    super.initState();

    var current = DateTime.now().toUtc(); // this is what you want
    Duration difference = startTime.difference(current);
    timer = Timer(Duration(microseconds: difference.inMicroseconds), () => checkForStart(timer));
[...]

dispose() {
    timer?.cancel();
    super.dispose();
  }

выход:

I/flutter ( 5819): 2021-02-16 15:00:00.000Z
I/flutter ( 5819): Run Forest!
I/chatty  ( 5819): uid=10154() 1.ui identical 65535 lines
I/flutter ( 5819): Run Forest!

Этот код гарантирует, что приложение запустится одновременно для всех, поскольку оно будет выполнять проверку с помощью таймера и запускать его на локальном устройстве в то же время, что и startTime, которое вы передали устройствам (NB: это версия переднего плана, это означает, что у всех должно быть открыто приложение)

Я не детализировал часть веб-сокета, потому что предположил, что у вас не возникнет проблем с его реализацией, если нет, вы можете взглянуть на этот репозиторий или другую документацию, учебные пособия и ответ stackOverflow. Пожалуйста, дайте мне знать, если это поможет.

person Antonin GAVREL    schedule 16.02.2021
comment
спасибо за этот ответ. У меня нет проблем с WebSockets или любой другой частью приложения, все в рабочем состоянии, я просто пытаюсь синхронизировать устройства для одновременного выполнения команд (или почти в одно и то же время, поскольку аппаратное обеспечение Android может быть очень быстрым или дешевым). и медленнее). Приложение должно работать на переднем плане независимо от того, потому что работа в фоновом режиме в какой-то момент отключает WebSockets (iOS быстрее, чем Android), это предусмотрено дизайном ОС. В то время как Android обладает некоторой гибкостью, iOS очень строга и в какой-то момент убивает их, если приложение слишком долго находится в фоновом режиме. - person zuboje; 18.02.2021