WebSocket in Go: gorilla/websocket library and standard implementation

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Go (Golang) WebSocket library: gorilla/websocket and standard net/http



WebSocket is a protocol that provides full-duplex communication between a client and server over a single long-lived TCP connection. Unlike classic HTTP, after the connection is established, data can be transmitted in both directions at any time, without constant requests from the client. This is an ideal solution for chats, real-time notifications, online games, and trading platforms.



In the Go (Golang) ecosystem, there are several ways to work with WebSocket. The most popular and time-tested library is gorilla/websocket. However, starting from Go 1.22, it became possible to implement a basic WebSocket server without third-party dependencies using the standard net/http package. In this article, we will cover both approaches in detail.



Installing the gorilla/websocket library



To get started with gorilla/websocket, install it via go get:



go get github.com/gorilla/websocket


The library provides a convenient API for creating both server and client parts. It handles the handshake, message framing, supports compression, and automatic ping/pong.



WebSocket server using gorilla/websocket



Let's look at an example of a simple echo server. The client sends a message, and the server sends it back:



package main

import ( "log" "net/http" "github.com/gorilla/websocket")

var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // allow any origin (for development) },}

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.Fatal(http.ListenAndServe(":8080", nil))}


Here, Upgrader converts a regular HTTP request into a WebSocket connection. The CheckOrigin function controls which domains are allowed to connect. In production, it is recommended to check specific origins.



WebSocket client using gorilla/websocket



An example of a client that connects to our server and sends a message:



package main

import ( "log" "os" "os/signal" "time" "github.com/gorilla/websocket")

func main() { interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt)

url := "ws://localhost:8080/echo" c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatal("dial:", err) } defer c.Close()

done := make(chan struct{})

// Goroutine for reading responses go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("read:", err) return } log.Printf("recv: %s", message) } }()

// Sending a message ticker := time.NewTicker(time.Second) defer ticker.Stop()

for { select { case <-done: return case t := <-ticker.C: err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) if err != nil { log.Println("write:", err) return } case <-interrupt: log

Recommendations