WebSocket — полнодуплексный протокол поверх TCP. Начинается как HTTP-запрос с Upgrade, после чего соединение переключается на WebSocket и обе стороны могут слать сообщения в любой момент.
import "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 {
return
}
defer conn.Close()
// читаем в одной горутине
for {
_, msg, err := conn.ReadMessage()
if err != nil {
break
}
// обработка
conn.WriteMessage(websocket.TextMessage, msg)
}
}
В Go каждое WebSocket-соединение обслуживается горутиной — это позволяет держать сотни тысяч одновременных коннектов. Популярные библиотеки: gorilla/websocket (классика, в archive mode) и nhooyr/websocket (современнее, поддерживает context). Важно: WriteMessage не потокобезопасен — если пишешь из нескольких горутин, нужен мьютекс или отдельная горутина-писатель с каналом.