Библиотека Gorilla WebSocket для Go (Golang)
Gorilla WebSocket — это одна из самых популярных и стабильных библиотек для работы с протоколом WebSocket в языке Go (Golang). Она является частью экосистемы Gorilla Toolkit и предоставляет разработчикам мощный, гибкий и производительный инструмент для создания real-time приложений: чатов, уведомлений в реальном времени, онлайн-игр, панелей мониторинга и многого другого.
Библиотека полностью реализует спецификацию RFC 6455, поддерживает как серверную, так и клиентскую стороны, а также автоматически обрабатывает фрагментацию сообщений, пинг/понг механизмы и контроль соединения. Gorilla WebSocket написана на чистом Go без внешних зависимостей, что делает её лёгкой и быстрой.
Основные возможности
- Полная поддержка WebSocket протокола (RFC 6455).
- Простой и интуитивно понятный API.
- Поддержка текстовых и бинарных сообщений.
- Автоматическое управление пинг/понг для поддержания соединения.
- Возможность проверки происхождения запроса (Origin).
- Поддержка сжатия сообщений (permessage-deflate).
- Работа с TLS/HTTPS.
- Высокая производительность и низкое потребление памяти.
Установка
Для установки библиотеки выполните команду:
go get github.com/gorilla/websocket
После этого импортируйте пакет в свой код:
import "github.com/gorilla/websocket"
Пример сервера WebSocket на Go
Ниже представлен простой сервер, который принимает WebSocket-соединения и отправляет обратно полученные сообщения (эхо-сервер):
package main
import (
"fmt"
"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) {
// Устанавливаем WebSocket соединение
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("Ошибка апгрейда:", err)
return
}
defer conn.Close()
// Бесконечный цикл чтения сообщений
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println("Ошибка чтения:", err)
break
}
log.Printf("Получено сообщение: %s", message)
// Отправляем сообщение обратно
err = conn.WriteMessage(messageType, message)
if err != nil {
log.Println("Ошибка записи:", err)
break
}
}
}
func main() {
http.HandleFunc("/echo", echoHandler)
fmt.Println("Сервер запущен на :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Клиент WebSocket на Go
Пример простого клиента, который подключается к серверу и отправляет сообщение:
package main
import (
"fmt"
"log"
"net/url"
"github.com/gorilla/websocket"
)
func main() {
u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/echo"}
fmt.Printf("Подключаемся к %s\n", u.String())
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("Ошибка подключения:", err)
}
defer conn.Close()
// Отправляем текстовое сообщение
err = conn.WriteMessage(websocket.TextMessage, []byte("Привет, WebSocket!"))
if err != nil {
log.Fatal("Ошибка отправки:", err)
}
// Читаем ответ
_, message, err := conn.ReadMessage()
if err != nil {
log.Fatal("Ошибка чтения:", err)
}
fmt.Printf("Получен ответ: %s\n", message)
}
Работа с несколькими клиентами (broadcast)
Для создания чата или системы уведомлений часто требуется рассылать сообщения всем подключённым клиентам. Вот пример простого менеджера соединений:
package main
import (
"fmt"
"log"
"net/http"
"sync"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
type Hub struct {
clients map[*websocket.Conn]bool
mu sync.Mutex
}
func (h *Hub) AddClient(conn *websocket.Conn) {
h.mu.Lock()
defer h.mu.Unlock()
h.clients[conn] = true
}
func (h *Hub) RemoveClient(conn *websocket.Conn) {
h.mu.Lock()
defer h.mu.Unlock()
delete(h.clients,