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/websocketThe 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 Also in library
Generating PDF Reports in JavaScript (Node.js): Puppeteer, PDFKit, jsPDF
Parsing HTML in C++: Overview of Gumbo, MyHTML, and htmlcxx Libraries
Working with Dates in Java: Overview of java.time, Joda-Time, and Apache Commons Libraries
Event Bus and Observer Pattern in Java: A Guide with Examples
JavaScript (Node.js) Standard Library: A Complete Overview