Отдельного экрана со настройками подключения нет: всё управление связью живёт в плашке в шапке и в полосе обрыва над лентой.
Чем удалённый агент отличается от местного
Удалённый агент — это агент, у которого движок запущен на сервере, а телефон ходит к нему через SSH-туннель.
- Местный агент живёт на телефоне, и с ним приложение говорит напрямую.
- Удалённый агент живёт на сервере, и между телефоном и сервером стоит туннель, который поднимается отдельно.
- У удалённого агента в шапке чата появляется плашка состояния связи, а у агента на телефоне такой плашки нет.
- Обрыв связи у удалённого агента ломает две вещи сразу: прямое соединение с движком и туннель, по которому к нему ходят.
- Из-за этого приложение следит за туннелем отдельно от соединения и умеет пересоздавать его без вас.
Три плашки в шапке
Плашка в шапке — это главный индикатор связи с удалённым агентом.
- Бирюзовая плашка Connected означает, что соединение живо и агент на связи.
- Жёлтая плашка Reconnecting… со стрелкой обновления означает, что соединение ещё не поднято, но приложение уже пробует.
- Красная плашка Disconnected со стрелкой обновления означает, что связи сейчас нет и подключение не идёт.
- Цвет и надпись меняются сами по мере того, как меняется связь, переключать их вручную не нужно.
- Плашка исчезает сама, как только связь восстановится.
Что делает тап по каждой плашке
У каждого состояния своё действие, поэтому тап всегда осмысленный.
- Тап по Connected спрашивает подтверждение: действительно ли закрыть туннель и отключиться от удалённого сервера.
- В окне подтверждения две кнопки: Disconnect отключает, Cancel ничего не делает.
- После подтверждения приложение закрывает туннель, отключается и выходит из чата.
- Тап по Reconnecting… не пересоздаёт туннель, он только сбрасывает ожидание и пробует подключиться раньше срока.
- Тап по Disconnected пересоздаёт туннель: снимает метку ручного отключения и просит поднять канал заново.
- Если туннель успел уцелеть, приложение просто подхватит его и не будет ничего пересоздавать.
- Если туннеля нет, приложение откроет новый, и в чате появится жёлтая плашка, пока идёт подключение.
Автоматическое переподключение
Приложение само следит за соединением и не ждёт, пока вы заметите обрыв.
- Обрыв сокета приложение замечает само и начинает подключаться заново.
- Паузы между попытками растут: сначала секунда, потом две, четыре и так далее, а потолок — тридцать секунд.
- Такой рост пауз бережёт телефон и сервер, чтобы не долбить переподключениями в плотном цикле.
- Пока идёт ожидание перед следующей попыткой, в шапке горит жёлтая плашка Reconnecting….
- Раз в двадцать секунд приложение проверяет, жива ли связь, даже если ничего не происходит.
- Если вы открываете экран в момент ожидания, приложение сбрасывает таймер и пробует подключиться сразу, не дожидаясь паузы.
Как поднимается туннель
Удалённому агенту туннель нужен всегда, поэтому им занимается отдельный сторож.
- Сторож включается, только когда соединение не живо, и выключается, как только связь вернулась.
- Каждый раз сторож спрашивает у бэкенда статус туннеля и смотрит, есть ли живой канал.
- Если туннель признан живым, он не трогается: приложение просто подключается к нему или переподключается к тому же порту.
- Если порт у туннеля другой, приложение переключает соединение на новый порт и перечитывает открытый тред.
- Если туннеля нет или он упал, сторож просит бэкенд создать его заново: это SSH-соединение, канал и запуск движка на сервере.
- Пересоздание туннеля делается не сразу, а через одну попытку, чтобы не дёргать сервер при каждом чихе.
- Между попытками сторож ждёт десять секунд.
- Сторож не мешает работать живому туннелю: если канал уже поднят, он не рвётся и не пересоздаётся заново.
- Несколько экранов могут звать сторожа одновременно, но новый круг работы он себе не заводит, пока предыдущий ещё идёт.
Ручное отключение — это запрет на автоподключение
Если вы отключились руками, приложение запоминает это и перестаёт лезть обратно.
- После ручного отключения туннель сам не поднимется, сколько бы попыток ни делал сторож.
- Запрет держится, пока вы не попросите подключиться снова: тап по Disconnected в шапке или кнопка подключения на главном экране.
- Запрет живёт только в памяти приложения: после перезапуска телефона он сбрасывается, и туннели снова могут подниматься сами.
- Закрытие чата руками отключением не считается: закрытый чат про туннель ничего не сообщает, и туннель продолжит подниматься сам.
Что происходит с перепиской при обрыве
Обрыв не стирает переписку, но пока связи нет часть событий до агента и от него не доходит.
- Пока связи нет, лента остаётся на месте и показывает то, что было известно на момент обрыва.
- Новые сообщения агента в это время не приходят и появятся после восстановления связи.
- Карточки вопросов и запросов разрешений во время обрыва убираются из ленты: ответить на них по старому сокету всё равно нельзя.
- После восстановления сервер сам присылает незакрытые запросы заново, и карточки собираются в ленте снова.
- Открытый тред перечитывается после восстановления, причём поверх текущего окна, поэтому лента не прыгает вниз и не теряет позицию чтения.
- При перечитывании запрашивается сводка последних шестидесяти ходов с краткими карточками вместо полных.
- Если в момент обрыва шёл ход агента, приложение отдельно догоняет его события и возвращает пропущенные шаги в ленту.
- Пока идёт перечитывание, повторный запрос не запускается: приложение ждёт паузу, чтобы реконнект и возврат из фона не мешали друг другу.
Что происходит с вашими сообщениями
Неотправленное не теряется молча — у сообщений есть состояние, и оно видно в ленте.
- Сообщение, которое не ушло из-за обрыва, помечается как ожидающее и остаётся в ленте.
- Почти сразу после восстановления связи ожидающие сообщения уходят сами, строго по порядку, в котором вы их писали.
- Если при отправке связь оборвалась так, что непонятно, дошло сообщение или нет, сообщение ждёт ручной проверки, а не отправляется молча ещё раз.
- Ручная отправка повторно сначала сверяется с сервером, чтобы не получить две копии одного сообщения.
- Очередь неотправленных сообщений после восстановления связи разбирается тоже: сначала догоняется активный ход, потом уходят сообщения, которые точно безопасны.
Полоса обрыва в чате
Когда открыт диалог, а связи нет, в чате появляется полоса с причиной и кнопкой.
- Полоса появляется только когда открыт диалог: в списке диалогов её нет.
- Жёлтая полоса с надписью WARNING и словами Disconnected — trying to reconnect… означает, что связь просто оборвалась и идёт восстановление.
- Красная полоса с надписью ERROR и словами Connection error означает, что причина обрыва известна, и первые пятьдесят символов сообщения показываются рядом.
- Справа на полосе есть кнопка Retry, которая пробует подключиться немедленно.
- Полоса исчезает сама, как только связь вернулась.
Статус связи в строке состояния
Строка состояния под лентой дублирует связь словами, чтобы статус был виден даже без плашки в шапке.
- Для удалённого агента с живой связью пишется connected · remote.
- Для удалённого агента без связи пишется Disconnected.
- Для агента на телефоне без связи пишется no connection · reconnecting….
- Эти подписи не заменяют плашку в шапке: плашка отвечает на вопрос «можно ли подключиться», строка состояния — на вопрос «что сейчас происходит».
Технические данные
| Параметр | Значение |
|---|---|
| Где видно состояние связи | плашка в шапке, полоса обрыва, строка состояния под лентой |
| У кого есть плашка в шапке | только у удалённого агента |
| Состояния плашки | Connected, Reconnecting…, Disconnected |
| Цвета плашек | бирюзовый, жёлтый, красный |
| Тап по Connected | окно подтверждения отключения |
| Тап по Reconnecting… | сброс ожидания и попытка подключиться |
| Тап по Disconnected | пересоздание туннеля и снятие запрета автоподключения |
| Подтверждение отключения | Disconnect или Cancel |
| Начальная пауза перед повторной попыткой | 1 секунда |
| Максимальная пауза перед повторной попыткой | 30 секунд |
| Проверка живости соединения | раз в 20 секунд |
| Пауза между кругами сторожа туннеля | 10 секунд |
| Пересоздание туннеля | не с первого круга, а через круг |
| Что считается живым туннелем | статус не пустой, не disconnected и не failed, и есть локальный порт |
| Пауза между повторными отметками в журнале | 60 секунд |
| Полоса обрыва | только при открытом диалоге |
| Кнопка на полосе обрыва | Retry |
| Показ причины ошибки | первые 50 символов сообщения |
| Через сколько уходят ожидающие сообщения | примерно через 750 мс после восстановления связи |
| Повторная отправка вслепую | запрещена, сначала сверка с сервером |
| Защита от дубля при ручной отправке | сверка по идентификатору сообщения |
| Пауза между автоматическими перечитываниями треда | 1,5 секунды |
| Сколько ходов запрашивается при перечитывании | последние 60, краткими карточками |
| Запрет автоподключения после ручного отключения | до явного подключения или перезапуска приложения |
Что агент умеет
- Агент на удалённом сервере продолжает работу, даже когда связь с телефоном пропала: его ход не прерывается обрывом.
- Агент может держать на сервере долгий ход, а вы после обрыва увидите его события, когда связь вернётся: пропущенные шаги догоняются автоматически.
- Агент может задать вопрос с разрешением прямо в момент обрыва, и после восстановления связи вопрос вернётся в ленту сам.
- Агент может вести несколько диалогов на одном удалённом сервере, и связь приложение держит для каждого диалога отдельно.
Ограничения
- Пока связи нет, новые события агента не приходят: в ленте видно только то, что было известно до обрыва.
- Вопросы и запросы разрешений во время обрыва исчезают из ленты и возвращаются только после восстановления связи.
- После ручного отключения туннель не поднимется сам: без явного подключения связь останется мёртвой.
- Запрет автоподключения не переживает перезапуск приложения: после перезапуска телефона туннель может подняться снова.
- Пока идёт восстановление связи, чат может выглядеть живым, хотя новых сообщений в нём не будет: ориентируйтесь на плашку и строку состояния.
- Если при обрыве непонятно, дошло сообщение или нет, оно не уйдёт само и будет ждать ручной отправки.
- Причину ошибки в полосе обрыва видно только частично: приложение показывает первые пятьдесят символов сообщения.
- При перечитывании после обрыва приложение просит у сервера сводку последних шестидесяти ходов, поэтому очень старые ходы в ленту не возвращаются.
- Автоматическое переподключение не поможет, если на сервере упал сам движок: это уже не туннель, и чинить это нужно на сервере.