· 2 мин чтения
WebSocket на стандартной библиотеке: что на самом деле происходит под new WebSocket()
Зачем в realtime-rooms написан собственный слой RFC 6455, какие нарушения протокола он проверяет и почему для продакшена всё равно лучше взять библиотеку.
Слой WebSocket в realtime-rooms (internal/ws, около 530 строк) написан только на стандартной библиотеке. Цель была учебной: увидеть, что скрывается под new WebSocket(...).
Рукопожатие
Это обычный GET с Connection: Upgrade, Upgrade: websocket, версией 13 и ключом в 16 байт (base64). Сервер отвечает 101 и Sec-WebSocket-Accept. Проверяется и Origin: тот же хост, значение из ALLOWED_ORIGINS или отсутствие заголовка у не браузерных клиентов, иначе 403.
Фреймы
Длина кодируется в 7, 16 или 64 бита, и неминимальная кодировка отвергается. Клиентские фреймы обязаны быть замаскированы, серверные нет. Управляющие фреймы не длиннее 125 байт и не фрагментируются. Размер проверяется по заголовку до выделения памяти, поэтому огромный фрейм не раздувает процесс.
Что проверяют тесты
Пример рукопожатия из RFC, пример замаскированного фрейма, фрагментация с ping посередине и 12 видов нарушений протокола, для каждого из которых проверяется код close.
Честная оговорка
Для продакшена обычно берут проверенную библиотеку: она прошла Autobahn Test Suite, умеет permessage-deflate и закрывает больше граничных случаев. Здесь Autobahn не запускался, расширения не поддерживаются. Это учебный слой, а не замена библиотеки.