WebSockets in ~50 Lines of Go

David Rieger
3 min readMay 24, 2021

If you are building an application that requires real-time transaction of data from server to client or bi-directional message transfers (such as Chat, Games, and certain types Notifications, etc.) you want to look at websockets.

Below I’m giving you — and guiding you through — the bare minimum of Go code required to build such a websocket.

At the end of this we will have two go applications that can be run independently from each other and will output following:

Simple websocket demo output. Left: client Right: server

Disclaimer

In an effort to keep it easy to read and highlight the parts actually directly required for websockets, I removed boiler plate code such as error handling. So beware that the below is not good — let alone clean — software.

Prerequisites

  • Go installed on your computer (I’m using go1.14 in my example) and a basic understanding on how to write and execute go code.
  • The Gorilla Websockets go package

The Basics

There are millions of tutorials and explanations on what a websocket exactly is. For all intents and purposes (and because I don’t have a much better explanation) we can think of a websocket as an elevated HTTP connection.

So to get to a websocket, we first establish a normal HTTP connection and then upgrade it (and it really is called upgrading). This will provide us with a websocket connection that we can hold on to and simple read to and write from (kind of like a go channel).

The Server

Below is the full code of a very basic server we can connect to and talk to via a websocket.

Full websocket server code: server.go

If we read through it (in order of execution) it will:

Line 59–63Start an HTTP server on localhost:8080 with an endpoint /ws.

Once an HTTP request is received on /ws:

L39Upgrade the HTTP connection to a websocket. This will return the actual connection type we need to hold on to for communicating.

L43, 15–24Start a consumer go routine which will read incoming messages from the socket and print it to the console.

L47, 50–57Send a couple of messages to the client by writing to the same socket connection.

And that’s all for the server.

The Client

Full websocket client code: client.go

Again reading through the code in order of execution, the client will:

L46, 10–15 Call the /ws endpoint on the server with a specific websocket dialer. This will return the connection object we need to hold on to for communicating.

L48, 17–28Start a consumer go routine which will read incoming messages from the socket and print it to the console (the exact same as on the server).

L50, 35–42Send a couple of messages to the client by writing to the same socket connection. Also the same as on the server, except with different messages

And that’s all for the client.

To run the programs, simply start the server first $ go run ./server and then the client in a separate terminal$ go run ./client.

By the way, the sleeps in both sendSomeMessages functions are entirely arbitrary and just here so you can follow the back and forth between server and client when you run the demo.

A final Note

The sending and receiving of messages between server and client happens entirely independent of each other. It’s not the usual request-response dynamic you get from HTTP connections. The server doesn’t respond to anything the client says, it just sends messages at will. A bit like UDP; but websockets do run on TCP and provide you with a transmission reliability that UDP doesn’t offer.

--

--