39.7 Scaling WebSocket Services: Sticky Sessions and Redis Pub/Sub

Right, so you’ve built a single-server WebSocket handler. It’s beautiful. It works. You feel like a genius. Then you try to deploy a second instance behind a load balancer, and suddenly User A on server 1 is sending messages into the void, trying to reach User B who is happily connected to server 2. Your brilliant real-time app has become a masterclass in disappointment. Welcome to the distributed systems party; it’s messy, and everyone’s here.

39.6 nhooyr.io/websocket: A Modern Alternative to Gorilla

Alright, let’s talk about the new kid on the block. You’ve probably heard of Gorilla/websocket—it’s been the de facto standard for years. But its maintainers have gracefully placed it into maintenance mode, which is a polite way of saying, “Maybe don’t start your new, mission-critical project with this.” Enter nhooyr.io/websocket (by the brilliant Eliot Nhooyer), a modern library that feels like it was designed specifically for the Go we write today: context-aware, io-friendly, and blessedly straightforward.

39.5 Server-Sent Events (SSE) as a Simpler Alternative

Now, let’s talk about the quiet, unassuming hero of the real-time web: Server-Sent Events, or SSE. While everyone’s busy setting up the plumbing for a full-duplex WebSocket connection, SSE is over there in the corner, effortlessly pushing data to your client with about 90% less drama. It’s the technology you use when you don’t need a full conversation, just a very informative monologue from your server. Think stock tickers, live notifications, or progress updates—that’s SSE’s sweet spot.

39.4 Managing Multiple WebSocket Connections with a Hub

Right, so you’ve got a single WebSocket connection working. It’s cute. You can send “hello” and receive “world.” Now, let’s get real. The whole point of this technology is to handle many connections, all talking to each other in real-time. You’re not building a walkie-talkie for two people; you’re building a party line. And the moment you have more than a handful of clients, the naïve approach—a global slice of connections and a for loop to broadcast—will absolutely fall on its face. It’ll be slow, prone to race conditions, and about as elegant as a donkey on roller skates.

39.3 Reading and Writing Messages in a WebSocket Handler

Right, so you’ve got your WebSocket connection open. Congratulations, the hard part is over. Now for the fun part: actually using the damn thing. This is where we move from handshakes and protocols to the actual business of shoving data back and forth. It’s simple in theory, but Go’s concurrency model means we get to do it the right way, which is both a blessing and a curse. Let’s break it down.

39.2 gorilla/websocket: The Standard WebSocket Library

Right, let’s talk about gorilla/websocket. If you’re doing WebSockets in Go, this is the library you reach for. It’s not technically the standard library, but it might as well be. It’s the de facto standard, battle-tested, and frankly, it’s excellent. The Go team themselves even maintains a link to it on the official golang.org website, which is about as close to a royal seal of approval as you get in our world.

39.1 WebSocket Protocol: Upgrading an HTTP Connection

Right, so you want real-time communication. You’ve tried long-polling and it felt like a hack from 2005. You’ve heard about Server-Sent Events (SSE) and they’re cool, but they’re a one-way street. You need a proper, full-duplex, real-time channel. That’s where WebSockets come in, and the first thing you need to understand is that it all starts with a slightly awkward handshake—an HTTP upgrade. Think of it like this: HTTP is a polite, transactional conversation. “I ask, you answer, we’re done.” WebSockets want to turn that into a pub where you can just shout updates at each other continuously. But you can’t just barge into the pub yelling; you have to ask the bouncer (the server) nicely to change venues. This asking is the HTTP Upgrade request.

— joke —

...