Required Imports
The first thing to do is to import the required packages. For this project, we will need the fmt package, net/http, and the gorilla package.
We can do these imports as:
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
Once imported, we can begin building our server.
Upgrade HTTP connection
The first step in our project is to take a HTTP connection and upgrade it to a WebSocket . We can do this using the websocket.Upgrade struct. It takes Read and Write Buffer size as defined in the source code below:
https://pkg.go.dev/github.com/gorilla/websocket#Upgrader
For our example, we will use the default options but set the CheckOrigin to a function that returns true. This will prevent the server from blocking the connection due to CORS.
CheckOrigin: func(r *http.Request) bool {
return true
},
}
Add Handler
Next, let us a HTTP handler when a client hits the /echo endpoint. We will define later in the main function.
conn, err := upgrader.Upgrade(w, r, nil)
iferr != nil {
log.Fatal(err)
return
}
defer conn.Close()
for {
mt, message, err := conn.ReadMessage()
iferr != nil {
log.Fatal(err)
break
}
fmt.Printf("recv: %s", message)
err = conn.WriteMessage(mt, message)
iferr != nil {
log.Fatal(err)
break
}
}
}
In the example above, we define a function that takes the ResponseWriter and a pointer to the http.Response.
We the upgrade the HTTP connection to the WebSocket protocol using the Upgrader function. Next, we use a for loop to listen and read incoming messages. We then print the message to the console and echo the message back to the client.
Add WebSocket Endpoint
The next step is to add a simple http handler for the WebSocket endpoint. We can use the function as:
websocketTemplate.Execute(w, "ws://"+r.Host+"/echo")
}
Create Client
To interact with the WebSocket serve, we need to create a client. We can do this by creating a simple HTML file from that uses JavaScript to open a WebSocket connection to the server. An example code is as shown:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Websocket Connection</title>
</head>
<body>
<input id="input" type="text" />
<button onclick="send()">Send</button>
<pre id="output"></pre>
<script>
const input = document.getElementById("input");
const output = document.getElementById("output");
const socket = new WebSocket("ws://localhost:8000/echo");
socket.onopen = function () {
output.innerHTML += "Status: Connected\n";
};
socket.onmessage = function (e) {
output.innerHTML += "Server: " + e.data + "\n";
};
functionsend() {
socket.send(input.value);
input.value = "";
}
</script>
</body>
</html>
Run Server
The last step is to define the routes and call the HTTP handlers in the main function. The code is as shown:
http.HandleFunc("/echo", echo)
http.HandleFunc("/", home)
http.ListenAndServe(":8000", nil)
}
Save the files and run:
Open the index.html file in your browser. You should see a connected message once the browser establishes a connection.
If you type any message into the field, the server responds it back.
The full source code of the program is as shown:
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
funcecho(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Fatal(err)
return
}
deferconn.Close()
for {
mt, message, err := conn.ReadMessage()
if err != nil {
log.Fatal(err)
break
}
fmt.Printf("recv: %s", message)
err = conn.WriteMessage(mt, message)
if err != nil {
log.Fatal(err)
break
}
}
}
funchome(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
}
funcmain() {
http.HandleFunc("/echo", echo)
http.HandleFunc("/", home)
http.ListenAndServe(":8000", nil)
}
Conclusion
This was a beginner’s guide to working with WebSocket in Go. In this guide, we covered how to upgrade a http connection to WebSocket protocol, read messages and responds messages back to the client.