Как устанавливается WebSocket соединение в браузере
Что проверяют
Знаете ли вы жизненный цикл объекта WebSocket и что браузер делает за вас сам. Следом обычно просят рассказать, как вы переподключаетесь после обрыва и как передаёте авторизацию.
Как отвечать
Начните с того, что new WebSocket(url, protocols) сразу запускает соединение: браузер резолвит адрес, открывает TCP, для wss:// проходит TLS и отправляет HTTP-запрос с Upgrade: websocket. Управлять этим запросом из кода нельзя.
- состояния:
readyStateпроходитCONNECTING(0),OPEN(1),CLOSING(2),CLOSED(3). Вызовsend()доopenбросаетInvalidStateError, поэтому сообщения до открытия складывают в очередь; - события:
open,message,error,close. Уerrorнет деталей по соображениям безопасности, причину смотрят вclose:code,reason,wasClean; - данные: строки или бинарные.
binaryTypeпо умолчанию"blob", для бинарного протокола удобнее"arraybuffer"; - закрытие:
close(code, reason), из скрипта разрешены только код 1000 и коды от 3000 до 4999; - обратное давление:
bufferedAmountпоказывает, сколько байт ещё не ушло в сеть; если он растёт, отправку стоит притормозить; - авторизация: произвольные заголовки в конструктор передать нельзя. Остаются cookie (браузер отправит их сам), короткоживущий токен в query-параметре или первое сообщение после
open.
Переподключение пишется руками: экспоненциальная задержка со случайным разбросом, чтобы тысячи клиентов не ломились на сервер одновременно после его рестарта. Для обнаружения «мёртвого» соединения нужен прикладной heartbeat: ping и pong протокола браузер обрабатывает сам и в JavaScript их не показывает.
Где спотыкаются
Вызывают send() сразу после конструктора и удивляются исключению. Соединение асинхронное, отправлять можно только после события open.
Считают, что close всегда приходит вовремя. При пропаже сети без закрывающего фрейма сокет может долго висеть в OPEN, пока не сработает таймаут TCP, отсюда и нужда в своём heartbeat.
Открывают ws:// со страницы на HTTPS. Браузер заблокирует это как смешанный контент; в продакшене только wss://, он к тому же лучше проходит через корпоративные прокси.