Как реализовать чат или переписку с использованием WebSocket?
Что проверяют
Понимаете ли вы жизненный цикл соединения и продумываете ли переподключение, порядок и доставку.
Как отвечать
Схема: клиент открывает соединение, обе стороны обмениваются сообщениями в обе стороны без новых запросов. Сервер держит соединения и рассылает сообщение участникам комнаты.
Что нужно предусмотреть на клиенте:
- аутентификация: заголовки в браузере задать нельзя, поэтому токен передают в параметре адреса или отправляют первым сообщением, а сервер до этого держит соединение неавторизованным;
- переподключение с экспоненциальной задержкой и джиттером: соединение рвётся при переходе из Wi-Fi в сотовую сеть, при засыпании вкладки, при перезапуске сервера;
- очередь исходящих: пока соединения нет, сообщения копятся и отправляются после восстановления;
- синхронизация после разрыва: клиент помнит идентификатор последнего полученного сообщения и после переподключения запрашивает пропущенные обычным HTTP. Без этого часть переписки теряется;
- оптимистичная отправка: сообщение показывается сразу с меткой «отправляется», подтверждение приходит от сервера с постоянным идентификатором;
- heartbeat: ping и pong, чтобы отличить живое соединение от повисшего.
На сервере: масштабирование требует общей шины (Redis Pub/Sub или брокер), потому что участники комнаты подключены к разным экземплярам; хранение истории в базе, а сокет только транспорт.
Альтернативы стоит назвать: SSE, если поток односторонний, и обычный опрос для редких обновлений.
Где спотыкаются
Не делают переподключение и теряют чат при первом же разрыве.
Полагаются на порядок и доставку, не сверяясь с историей после реконнекта.
Не думают о масштабировании и держат список подключений в памяти одного процесса.
Отправляют токен и не проверяют его на сервере, считая соединение доверенным.