> Что такое WebSocket и как он работает (Go)

Уровень: junior · Роль: backend · Категория: Технические вопросы

Компании: Aston

Стек: Go

> Пример ответа

Короткий ответ

WebSocket - это протокол поверх TCP, который обеспечивает постоянное двустороннее соединение между клиентом и сервером. В отличие от HTTP, где каждый запрос открывает новое соединение, WebSocket держит канал открытым, позволяя обеим сторонам отправлять сообщения в любой момент без повторного handshake. Работает через HTTP-апгрейд: клиент отправляет обычный HTTP-запрос с заголовком Upgrade: websocket, сервер отвечает 101 Switching Protocols, и дальше идёт бинарный или текстовый обмен кадрами.

Подробное объяснение

WebSocket решает проблему HTTP, который является request-response протоколом: сервер не может инициировать отправку данных клиенту без запроса. Раньше для этого использовали polling или long polling, но это создавало лишнюю нагрузку и задержки.

Процесс установки соединения:

  1. Клиент отправляет HTTP-запрос с заголовками Upgrade: websocket и Connection: Upgrade, плюс Sec-WebSocket-Key (случайная строка в base64).
  2. Сервер проверяет заголовки, вычисляет Sec-WebSocket-Accept как SHA-1 от конкатенации ключа и GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11, затем base64.
  3. Сервер отвечает 101 Switching Protocols с заголовком Sec-WebSocket-Accept.
  4. Соединение переключается на WebSocket-протокол, дальше идёт обмен кадрами (frames).

Кадр состоит из заголовка (FIN, opcode, mask, length) и payload. Клиентские кадры обязательно маскируются (mask bit = 1), серверные - нет. Opcode определяет тип: text (1), binary (2), close (8), ping (9), pong (10).

Соединение закрывается через close-кадр, после чего TCP-соединение завершается.

В Go для работы с WebSocket обычно используют библиотеку gorilla/websocket или стандартный пакет golang.org/x/net/websocket, но gorilla - де-факто стандарт.

На практике

Для backend-разработчика на Go важно понимать:

  • WebSocket-соединение занимает ресурсы: горутину на соединение, память на буферы. Нужно управлять лимитами и таймаутами.
  • Нужно обрабатывать ping/pong, чтобы определять мёртвые соединения.
  • Конкурентный доступ к соединению: писать в соединение можно только из одной горутины, иначе будет race condition. Обычно используют канал для отправки сообщений.
  • WebSocket не гарантирует доставку и порядок - это не message queue. Для надёжности поверх WebSocket строят свои протоколы (ack, retry).
  • Балансировка нагрузки: WebSocket-соединение привязано к конкретному серверу, нужен sticky sessions или отдельный pub/sub брокер (Redis, NATS) для синхронизации между инстансами.

Пример кода

GO
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true // для примера, в проде проверять origin
},
}
func handleWS(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer conn.Close()
// обработка сообщений
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println("read error:", err)
break
}
log.Printf("received: %s", message)
// эхо-ответ
if err := conn.WriteMessage(messageType, message); err != nil {
log.Println("write error:", err)
break
}
}
}
func main() {
http.HandleFunc("/ws", handleWS)
log.Fatal(http.ListenAndServe(":8080", nil))
}

Как отвечать на собеседовании

Начни с короткого определения, затем опиши handshake и отличие от HTTP. Упомяни, что WebSocket работает поверх TCP, а не заменяет его. Скажи про кадры и маскирование. Если спросят про Go - упомяни gorilla/websocket и проблему конкурентного доступа к соединению. Не углубляйся в бинарный формат кадра, если не просят. Хорошо показать понимание, зачем нужен ping/pong и как обрабатывать закрытие соединения.

Что проверяет интервьюер

  • Понимание разницы между HTTP и WebSocket.
  • Знание handshake-процедуры и заголовков.
  • Понимание модели обмена сообщениями (full-duplex).
  • Осознание ограничений: нет гарантии доставки, ресурсоёмкость, проблемы с масштабированием.
  • Практические навыки: как обрабатывать конкурентность, таймауты, закрытие соединений.

Типичные ошибки

  • Путают WebSocket с HTTP/2 server push или SSE (Server-Sent Events). SSE - односторонний, только сервер → клиент.
  • Думают, что WebSocket сам по себе обеспечивает надёжную доставку - это не так, нужен свой слой подтверждений.
  • Не учитывают, что клиентские кадры маскируются, а серверные нет - это требование протокола, а не деталь реализации.
  • Пишут в соединение из нескольких горутин без синхронизации - это приводит к панике или повреждению данных.
  • Забывают про heartbeat (ping/pong) и соединение молча умирает, а сервер держит мёртвые горутины и память.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью