Фото Jens Kreuter с Unsplash
Фото Jens Kreuter с Unsplash

Сегодня я хочу рассказать вам о том, как я пробовал реализовать функционал «Нет подключения» на SmartTV для платформ webOS и Tizen. Это звучит довольно просто, и вы можете спросить меня, что ты можешь рассказать нам нового, но поверьте, я могу :)

Эта статья о том, как обнаружить сетевое подключение.

На данный момент я знаю 3 способа, как проверить сетевое соединение, и каждый из них имеет свои плюсы и минусы, давайте пройдемся по каждому.

1. Проверка состояния сети в браузере

В браузере можно подписаться на изменение состояния сети. И я начал с этой реализации.

Это отлично работает, когда вы тестируете эту функциональность в браузере ПК/ноутбука, но через некоторое время мне сообщили, что она не работает. Почему?

На телевизорах эта реализация работает только при отсоединении кабеля от телевизора, а в реальности у нас ошибки подключения к сети в других случаях. Тестовым случаем было отсоединение кабеля LAN от роутера и браузер абсолютно не определяет этот случай, он пишет, что браузер в сети.

Перейдем к следующей реализации, где мы можем обнаружить этот случай.

2. Проверка состояния сети с помощью нативной SmartTV SDK

WebOS и Tizen поддерживают проверку сетевых подключений с помощью собственного SDK.

На WebOS используется Connection Manager и можно вызывать разовую проверку или подписаться на изменения.

На Tizen используется Network API, и также можно вызывать разовую проверку или подписаться на изменения.

Ожидаемый результат использования SDK был в том, что SmartTV должен понимать, есть сетевое подключение или нет.

Реальность выглядит иначе...

Tizen:

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

При отключении LAN-кабеля от роутера в течение 30–40 секунд ничего не происходит, только после этого времени Tizen определяет, что сети нет. Это больше, чем ничего, и можно с этим работать.

WebOS:

Отключение кабеля LAN от телевизора приводит к немедленному изменению состояния сети.

Отключение кабеля локальной сети от маршрутизатора не приводит к изменению состояния сети ни через 30 секунд, ни 1 минуту, ни 1 час. Это было неожиданностью для меня.

В дополнение ко всему, так как WebOS не понимает, что интернета нету, то он позволяет запускать приложения без него, будьте готовы к такому повороту.

В этот момент я начал думать о том, как же реализовать эту функциональность для всех платформ и с небольшой задержкой.

3. Проверка состояния сети с помощью периодического опроса BE или стороннего эндпоинта

Я видел только одно решение, как достичь цели, и это периодический опрос. Для этого пинга можно использовать эндпоинт на сервере или стороннюю конечную точку (например, Google).

Если статус ответа между [200, 300), можно сказать, что соединение есть.

Если какая-то ошибка, можно сказать, что что-то не так и нет сети.

Данная реализация корректно работает на WebOS и Tizen во всех случаях с задержкой в 2 сек.

Можно добавить таймер для обнаружения, если что-то не так, и отменить запрос вручную через некоторое время.

Нельзя использовать AbortController и fetch здесь, потому что Chromium на Tizen 4 не знает такого интерфейса, поэтому я использовал XMLHttpRequest.

В данном случае у меня были ложноположительные результаты через 10–40 мин, когда запросы отправляются без ответа в течение 500 мс, ТВ обрабатывает запрос с меньшей скоростью, чем ПК, и вы должны это понимать.

Также может быть ложноположительный результат, когда сервер недоступен в текущий момент или имеет высокую нагрузку, и показывается экран "Нет подключения", но после повторной попытки он доступен. Это выглядит странно. Возможным решением этой проблемы может быть реализация окна решения, где вы можете проверить большинство положительных результатов, но это увеличивает время задержки между потерей соединения и отображением экрана.

Заключение

Не всегда простая функциональность может быть такой простой, как показалось на первый взгляд, особенно при работе со SmartTV.

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

Комментарии (10)


  1. nkretov
    10.01.2022 21:42

    Добрый день! Можете подсказать в строчке webOS.service.request('luna://com.webos.service.connectionmanager' - luna это какой-то протокол? чот быстро нагуглить не смог.

    и в этом сниппете:

        if (value === webapis.network.NetworkState.GATEWAY_CONNECTED) {
          callback(true);
        } else if (value === webapis.network.NetworkState.GATEWAY_DISCONNECTED) {
          callback(false);

    кажется что проверяется сетевая связность до гейтвея локальной сети а не интернета)


    1. yantishko Автор
      10.01.2022 21:47
      +2

      Добрый,

      Это сервис встроенный в webOS, который предоставляет API для работы нативными функциями операционки

      https://webostv.developer.lge.com/api/webos-service-api/intro-lunaservice/


      1. nkretov
        10.01.2022 22:07

        спасибо


    1. yantishko Автор
      11.01.2022 08:59

      Это пример из официальной документации Tizen.

      https://developer.samsung.com/smarttv/develop/api-references/samsung-product-api-references/network-api.html#Network-NetworkStateChangedCallback

      Интернет как такойвой Tizen не позволяет проверить, а этот эвент отрабатывает одновременно с нотификацией от тайзена, что соединения нету.


  1. dynamicult
    11.01.2022 01:41
    +1

    const request = new XMLHttpRequest();
    //....//
    request.onload = () => {
        if (stopApiCallTimer) clearTimeout(stopApiCallTimer);
        setNetworkConnection(this.request?.status >= 200 && this.request?.status < 300);
    };

    this.request у вас всегда будет undefined, потому что request у вас не является out-of-scope variable, и в вашем хендлере this указывает либо на контекст globalThis, где никакого request нет, либо никуда не указывает вовсе.


    1. yantishko Автор
      11.01.2022 08:52

      Спасибо, опечатка. Не везде исправил для примера в статью.

      Исправил в статье


  1. Vinni37
    11.01.2022 18:48

    Решение к которому вы пришли (если обстрагироваться от реализации), присуще по своей сути любой ОС или ЯП и т.д. Ведь что такое для устройства отсутствие сети? Правильный ответ будет, отсутствие Линка на интерфейсе. ИМХО что либо другое этот отсутствие связи между конечными узлами, что как раз и можно диагностировать "пингом" или как в данном случае поднятием конекта. Ведь даже если бы ОС давала такое апи, там под капотом было бы тоже самое, пусть и не в виде проверки кода http ответов.


    1. yantishko Автор
      12.01.2022 17:45

      Получается, что так.

      И вывод, что Tizen под капотом что-то делает такое самостоятельно, хоть и с большим интервалом, а WebOS такое не делает вообще


      1. Vinni37
        12.01.2022 18:01

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


        1. yantishko Автор
          12.01.2022 18:21

          Соглашусь, особенно после того, как в документации WebOS, в примерах кода js, я нашёл очень много ошибок и не валидного кода, который там уже дааавно.

          Отправил им правки по документации, пока реакции нет :)