How to Create Golang Websockets

The WebSockets protocol is a new way to communicate in real-time, but it’s not as straightforward as you might think. In fact! Even close!! The following tutorial will teach how one makes their first-ever web socket server from scratch with Go by following the easy steps.

Required Imports

The first step is to import the necessary packages. For this project, you will need the FMT, NET/HTTP, and Gorilla packages.

Next, you may import these items using the following example.

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

After you have imported everything, you can begin developing.

Upgrade HTTP Connection

The initial stage in our project is to convert an HTTP connection to a WebSocket. We can do this with the use of a WebSocket. Improve the structure. It requires the following Read and Write Buffer sizes, as described in the source code.

The following example below will show the default parameters but change the CheckOrigin to a function that returns true. This prevents the server from blocking the connection because of CORS.

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

Add HTTP Handler

Next, let us add an HTTP handler when a client hits the /echo endpoint defined later in the primary function.

func echo(w http.ResponseWriter, r *http.Request) {
    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
        }
    }
}

As the above shows, you build a function that accepts a ResponseWriter and the relevancy of an HTTP.Response.

Using the Upgrader function, convert the HTTP connection to the WebSocket protocol. Next, utilize a for loop to listen for and read incoming messages. The message is then printed to the console and echoed back to the client.

Add WebSocket Endpoint

The following step is to implement a primary HTTP handler for the WebSocket endpoint with the following function.

func home(w http.ResponseWriter, r *http.Request) {
websocketTemplate.Execute(w, "ws://"+r.Host+"/echo")
}

Create HTTP Client

To communicate with the WebSocket server, you must first establish a client by developing a specific HTML page that employs JavaScript to ascertain a WebSocket reference to the server. An example code is as shown:

index.html
<!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>

Initiate Serverside

The last step is to declare the routes and invoke the HTTP handlers in the main function, which can be done using the following.

funcmain() {
    http.HandleFunc("/echo", echo)
    http.HandleFunc("/", home)
    http.ListenAndServe(":8000", nil)
}

Now, save the files and execute.

go run ws.go

Launch your favorite Internet browser and navigate to the index.html file. Once the browser connects to the test page, it creates a connection which you should see a connected message.

Now, you can write a message into the field, the server will respond.

The complete source code of the program is as shown.

package main
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)
}

Comments and Conclusion

In the tutorial, you have covered how to upgrade an HTTP connection to the WebSocket protocol, read messages, and respond to messages from the client. You have also looked at how you can use WebSocket in your applications. Be sure to check out our other posts on Golang for more examples of using this powerful tool. Thanks for reading!



Follow LinuxCapable.com!

Like to get automatic updates? Follow us on one of our social media accounts!