Какие протоколы используются для взаимодействия браузера с сервером
Что проверяют
Знаете ли вы, что происходит на проводе между браузером и вашим Go-сервисом, и как это отражается в коде на net/http. Следом обычно спрашивают, как в Go сделать обновление данных в реальном времени или почему gRPC нельзя просто вызвать из браузера.
Как отвечать
Разложите протоколы по назначению и сразу привяжите к Go:
- HTTP/1.1: запрос-ответ поверх TCP с keep-alive. Браузер держит несколько соединений на хост, запросы в одном соединении идут по очереди;
- HTTP/2: бинарные фреймы, мультиплексирование потоков в одном соединении, сжатие заголовков HPACK. Браузеры используют его только поверх TLS, а
http.Serverвключает HTTP/2 сам приListenAndServeTLS, обработчики не меняются; - HTTP/3: работает поверх QUIC на UDP, потеря пакета не тормозит соседние потоки. В стандартной библиотеке его нет, берут
quic-goили терминируют HTTP/3 на балансировщике; - TLS: даёт HTTPS. В проде сертификат часто висит на Nginx или ингрессе, и до Go доходит обычный HTTP;
- WebSocket: начинается как HTTP-запрос с заголовком
Upgrade, дальше двусторонний канал. В стандартной библиотеке сервера нет, используютgorilla/websocketилиcoder/websocket; - SSE: односторонний поток событий по обычному HTTP. В Go это ответ с
Content-Type: text/event-streamиFlushчерезhttp.Flusherпосле каждого события; - gRPC: браузер не управляет фреймами HTTP/2 и трейлерами, поэтому нужен gRPC-Web с прокси или протокол Connect поверх обычного HTTP.
Где спотыкаются
Называют WebSocket протоколом, не связанным с HTTP. Рукопожатие идёт через HTTP, и прокси перед сервисом должен пропускать Upgrade, иначе соединение не установится.
Думают, что HTTP/2 надо включать руками. Для TLS-сервера на net/http это поведение по умолчанию, а без TLS браузер HTTP/2 не использует вовсе.
Держат долгие соединения и забывают про таймауты. WriteTimeout у http.Server оборвёт SSE-поток, а без проверки r.Context() горутины продолжают работать после ухода клиента.