Ответ вслух Senior WebSocket и SSE обновлено

Надёжный WebSocket-клиент

Вопрос

Как бы ты сделал надёжный клиент WebSocket для чата, который переживает обрывы сети?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Начну с переподключения: при close или ошибке клиент ждёт и пробует снова, задержка растёт экспоненциально, например 1, 2, 4 секунды до потолка в 30, плюс случайный джиттер, чтобы после рестарта сервера тысячи клиентов не пришли одновременно.

Что должно прозвучать в ответе

  • Реконнект с экспоненциальной задержкой и джиттером, сброс задержки после успеха

  • Heartbeat: ping/pong с таймаутом, при пропуске закрыть и переподключиться

  • Нумерация сообщений: после реконнекта клиент сообщает последний id, сервер досылает пропущенное

  • Очередь исходящих сообщений с клиентскими id, идемпотентность на сервере против дублей

  • Реакция на `online`/`offline` и видимость вкладки, повторная авторизация при истёкшем токене

Что могут спросить следом

  • Зачем джиттер в задержке реконнекта?
  • Как избежать дублей сообщения после повторной отправки?
  • Что делать, если сервер перезапускается и все клиенты переподключаются разом?

Разбор

Начну с переподключения: при close или ошибке клиент ждёт и пробует снова, задержка растёт экспоненциально, например 1, 2, 4 секунды до потолка в 30, плюс случайный джиттер, чтобы после рестарта сервера тысячи клиентов не пришли одновременно. Обрыв не всегда виден сразу, поэтому нужен heartbeat: раз в 20-30 секунд ping, и если pong не пришёл за таймаут, соединение считается мёртвым. Чтобы ничего не потерять, у каждого сообщения на сервере есть последовательный id, клиент помнит последний полученный и после реконнекта просит всё, что было после него. Исходящие сообщения кладу в очередь с клиентским uuid и отправляю повторно, пока не придёт подтверждение, а сервер по этому uuid отбрасывает дубли. Ещё слушаю события online и offline, чтобы не долбиться в сеть без интернета, и обновляю токен перед переподключением, если он истёк.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.