Gorilla WebSocket: мощный инструмент для реального времени на Go
В современной веб-разработке потребность в обмене данными в реальном времени становится всё более актуальной. Будь то чаты, онлайн-игры, мониторинг серверов или биржевые котировки — WebSocket является стандартом де-факто для двусторонней связи между клиентом и сервером. Для языка Go (Golang) одной из самых популярных и стабильных библиотек для работы с WebSocket является Gorilla WebSocket.
Библиотека gorilla/websocket входит в экосистему Gorilla Toolkit — набора высококачественных пакетов для веб-разработки на Go. Она предоставляет полный набор функций для создания WebSocket-серверов и клиентов, поддерживает все основные протоколы (RFC 6455) и отличается простотой использования.
Основные возможности Gorilla WebSocket
- Полная поддержка протокола WebSocket — работа с текстовыми и бинарными фреймами, фрагментация сообщений, контрольные фреймы (ping/pong).
- Удобное API — минималистичный интерфейс с функциями
ReadMessageиWriteMessage. - Поддержка TLS/SSL — защищённые WebSocket-соединения (wss://).
- Гибкая настройка — возможность задавать таймауты, размеры буферов, проверять происхождение запросов.
- Совместимость с HTTP — легко интегрируется с любым HTTP-сервером Go (net/http).
- Работа с контекстами — поддержка
context.Contextдля отмены операций.
Установка библиотеки
Для установки Gorilla WebSocket выполните команду в терминале:
go get github.com/gorilla/websocket
После этого добавьте импорт в ваш Go-файл:
import "github.com/gorilla/websocket"
Базовый пример WebSocket сервера
Рассмотрим простейший эхо-сервер, который принимает WebSocket-соединения и отправляет обратно полученные сообщения.
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // Разрешаем все источники (для разработки)
},
}
func echoHandler(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("/echo", echoHandler)
log.Println("Server started on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Подробное объяснение кода
- Upgrader — это структура, которая преобразует обычный HTTP-запрос в WebSocket-соединение. В примере мы разрешаем запросы с любых источников (поле
CheckOrigin). В продакшене стоит проверять конкретные домены. - Upgrade — основной метод, который берёт
http.ResponseWriterи*http.Requestи возвращает*websocket.Conn. - ReadMessage — блокирующий вызов, который ожидает новое сообщение от клиента. Возвращает тип сообщения (текст или бинарные данные) и сами данные.
- WriteMessage — отправляет сообщение обратно клиенту. В данном случае мы просто возвращаем то же самое, что получили.
Клиент на WebSocket (Gorilla)
Библиотека также позволяет легко создавать WebSocket-клиентов. Вот пример подключения к серверу и отправки сообщения:
package main
import (
"log"
"net/url"
"github.com/gorilla/websocket"
)
func main() {
u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/echo"}
log.Printf("Connecting to %s", u.String())
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("Dial error:", err)
}
defer c.Close()
// Отправляем сообщение
err = c.WriteMessage(websocket.TextMessage, []byte("Hello, WebSocket!"))
if err != nil {
log.Fatal("Write error:",