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

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

Компании: Aston

Стек: Go

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

WebSocket - это протокол связи, обеспечивающий полнодуплексное двустороннее соединение между клиентом и сервером поверх одного TCP-соединения. В отличие от HTTP, который работает по запрос-ответной модели, WebSocket позволяет серверу инициировать отправку данных клиенту без предварительного запроса, что критично для real-time приложений (чаты, уведомления, онлайн-игры).

Как работает WebSocket:

  1. Ручкопожатие (handshake): Клиент отправляет HTTP-запрос с заголовком Upgrade: websocket и Connection: Upgrade. Сервер отвечает статусом 101 Switching Protocols, подтверждая переход на WebSocket. После этого соединение "апгрейдится" с HTTP на WebSocket.

  2. Фреймы данных: После установки соединения данные передаются в виде фреймов (кадров). Каждый фрейм содержит opcode (тип данных: текст, бинарные данные, закрытие, ping/pong) и полезную нагрузку. Протокол поддерживает фрагментацию сообщений.

  3. Ping/Pong: Для поддержания соединения и проверки жизнеспособности используются управляющие фреймы ping (от сервера) и pong (от клиента).

  4. Закрытие: Любая сторона может инициировать закрытие, отправив фрейм с opcode 0x8. После получения подтверждения соединение разрывается.

Пример на Go (используя стандартную библиотеку net/http и gorilla/websocket):

GO
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("Upgrade failed:", 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", wsHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}

Ключевые особенности в Go:

  • Upgrader из gorilla/websocket (или nhooyr.io/websocket) преобразует HTTP-соединение в WebSocket.
  • Чтение/запись блокирующие - для параллельной обработки используйте горутины.
  • Важно обрабатывать закрытие соединения и ошибки, чтобы избежать утечек.

WebSocket идеален для сценариев, где требуется низкая задержка и постоянный обмен данными, но не подходит для простых REST-запросов из-за накладных расходов на поддержание соединения.

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

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