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