Как расследовать WebSocket 1006 и безопасное восстановление соединения
Контекст
ARMCP представлен как worldwide web and mobile SaaS для technology, Web3, social и community workflows. Языки продукта и сообщества ровно EN, RU, FR и ES. ARMCP Desk работает, ARMCP Analytics и ARMCP Chain находятся в разработке. Это описание не означает, что ARMCP реализует каждый механизм WebSocket из руководства.
Что означает 1006
Код 1006 обозначает аномальное закрытие, когда клиент не получил корректный кадр Close. Это локальный итог, а не значение, которое сервер должен отправить. TCP мог оборваться, процесс мог остановиться, прокси мог применить тайм-аут, а мобильная сеть могла сменить маршрут. Клиент объединяет эти причины, поэтому нужен набор согласованных доказательств.
Точное наблюдение
Запишите экран, действие пользователя, длительность соединения, последнее подтвержденное сообщение, версию клиента, платформу, тип сети и время с часовым поясом. Формулировка должна быть воспроизводимой: после определенного интервала клиент показал 1006, последняя последовательность была известна, новая попытка началась через измеримое время.
Временная шкала
Сведите события в UTC и сохраните исходные отметки. Клиентский monotonic clock полезен для длительностей, но не сравнивается напрямую с серверным wall clock. Таблица включает открытие, HTTP Upgrade, последний ping, последний pong, последнее прикладное сообщение, смену сети, закрытие, reconnect и подтверждение нового согласованного состояния.
Доказательство Upgrade
Зафиксируйте статус 101 Switching Protocols, заголовки Upgrade и Connection, subprotocol и расширения. Не сохраняйте cookie, Authorization и одноразовые подписи. Достаточно маскированного correlation ID. Если 101 был получен, расследуйте установленный канал. Если его не было, отделите обычный HTTP-отказ от аномального закрытия WebSocket.
Транспорт и операция
WebSocket дает транспорт, а приложение добавляет команды, подтверждения и последовательности. Канал может быть открыт, когда прикладной поток уже застрял. TCP может оборваться после выполнения важной команды. Храните раздельные состояния транспорта и операции, чтобы не повторить изменение, которое сервер уже применил.
Heartbeat и тайм-ауты
Составьте список лимитов клиента, сервера, балансировщика, reverse proxy, CDN, NAT и мобильного оператора. Самый короткий фактический лимит определяет поведение. Различайте WebSocket control ping и прикладной heartbeat. Слишком частые проверки расходуют батарею и сеть, слишком редкие поздно обнаруживают мертвый канал.
Мобильный жизненный цикл
Сопоставьте 1006 с background, foreground, блокировкой экрана, power saving, сменой Wi-Fi и мобильной сети. Платформа не всегда гарантирует постоянный сокет. После возврата на передний план клиент должен проверить актуальность сессии, а не считать старый объект соединения действующим.
Сеть и NAT
Переключение сети может оставить сокет в промежуточном состоянии. Маршрут уже исчез, но ошибка проявляется при следующей записи или тайм-ауте. В лаборатории проверьте короткий airplane mode, переход между сетями, задержку, jitter и умеренную потерю пакетов. Не создавайте несанкционированную нагрузку на публичный сервис.
Прокси и балансировщик
Найдите записи по безопасному correlation ID. Проверьте причины завершения upstream и downstream, переданные байты, возраст соединения и внутренний код сброса. Клиент может увидеть 1006 после idle timeout, максимального возраста, перезапуска конфигурации или потери upstream. Обычный HTTP access log после Upgrade часто недостаточен.
Деплой
Сопоставьте инцидент с выкладкой, масштабированием, eviction, OOM и остановкой процесса. Корректный drain прекращает прием новых соединений и дает существующим клиентам время завершить работу. Резкое уничтожение процесса часто превращается в 1006. Тестируйте drain в staging и проверяйте восстановление позиции потока.
Минимизация данных
Диагностика не должна записывать полные кадры с токенами и персональными данными. Храните тип сообщения, размер, последовательность, время, обезличенный идентификатор и результат обработки. Полезную нагрузку заменяйте хешем или тестовым значением. Ограничьте срок хранения и круг доступа.
Детерминированный тест
Опишите начальное состояние, тестовую учетную запись, версии клиента и сервера, регион и шаги. Один сценарий меняет один фактор. Сначала выполните базовую сессию, затем добавьте задержку, короткий разрыв, переключение сети и перезапуск тестового узла. Повторите варианты и сохраните успешные и неуспешные прогоны.
Размер и backpressure
На стенде постепенно увеличивайте безопасный тестовый payload и отмечайте границу отказа. Следите за bufferedAmount, глубиной очереди, временем обработки и памятью. Быстрый производитель и медленный потребитель могут уничтожить процесс. Политика определяет замедление, объединение обновлений, отбрасывание устаревших событий или корректное закрытие.
Ограниченный reconnect
Бесконечный мгновенный reconnect создает шторм. Используйте экспоненциальную задержку с jitter, верхний предел и ограничение параллельных попыток. Сбрасывайте счетчик только после стабильной сессии, уважайте offline и жизненный цикл приложения. Измеряйте число попыток, время восстановления и долю прекращенных повторов.
Семантика команд
Каждая изменяющая команда получает устойчивый идентификатор и политику повторов. Сервер распознает дубликат и возвращает прежний результат. После 1006 клиент не отправляет все вслепую, а выясняет подтвержденные последовательности и авторитетное состояние. Неидемпотентная операция требует проверки или явного решения пользователя.
Восстановление потока
При монотонной последовательности клиент сообщает последний примененный номер. Сервер воспроизводит пропуск из ограниченного журнала или требует полный снимок. Снимок и последующие события должны иметь общую точку отсечения. Проверьте разрыв между получением и применением сообщения, чтобы обнаружить дубликаты и пропуски.
Гонка сокетов
После reconnect старое соединение может поздно вызвать обработчик. Назначайте каждой попытке поколение или session epoch и игнорируйте события неактуального поколения. Закрывайте таймеры, отписывайте listeners и отменяйте старые запросы. Особенно важен быстрый переход background и foreground на мобильном устройстве.
Постоянная ошибка
Истекшая аутентификация, отозванный доступ и несовместимый subprotocol требуют другого пути, чем краткий сетевой сбой. Ограничьте циклы обновления токена. Если доступ отклонен, остановите reconnect и покажите понятное действие входа или обращения к администратору, не раскрывая секреты в журналах.
Метрики
Группируйте метрики по платформе, версии, региону, стадии соединения и причине. Не используйте полный URL, токен или user ID в labels. Полезны established connections, abnormal closures, median session age, reconnect success, resume gap, duplicate suppression и time to consistent state.
Матрица приемки
Матрица включает браузер, мобильное приложение, Wi-Fi, мобильную сеть, foreground, background, короткий и длительный разрыв, перезапуск сервера и drain прокси. Для каждой клетки задайте ожидаемый результат, время обнаружения, схему reconnect, способ восстановления и критерий отсутствия потери или дубликата.
Интерфейс
Различайте потерю подключения, восстановление, необходимость входа и неподтвержденные изменения. Не показывайте зеленый статус только потому, что объект WebSocket существует. Доступность требует текста, стабильного фокуса и корректного объявления состояния. На узком экране сообщение не перекрывает безопасное действие.
Готовность
Исправление принято, когда контролируемый сценарий не теряет подтвержденные данные, дубликаты подавляются, reconnect ограничен, состояние становится согласованным за измеримое время, а журналы объясняют результат без секретов. Нужны повторяемые тесты, сравнение до и после и заранее определенный порог отката.
Заключение
WebSocket 1006 полезен как сигнал, но слишком широк для диагноза. Надежное расследование соединяет временную шкалу, Upgrade, heartbeat, сетевые переходы, прокси, жизненный цикл процесса и прикладные подтверждения. Фактическое описание продукта доступно на официальном сайте ARMCP.