Sling Academy
Home/Golang/Understanding WebSocket Protocols and Upgrades in Go

Understanding WebSocket Protocols and Upgrades in Go

Last updated: November 26, 2024

In recent years, WebSocket has become a crucial protocol for real-time web applications that necessitate full-duplex communication channels over a single TCP connection. In this article, we’ll explore WebSocket protocols, how they operate, and ways to implement them, particularly focusing on Go, a language known for its efficiency and simplicity.

What Are WebSockets?

WebSockets offer a persistent connection between a client and server, enabling either party to send data at any time without needing to establish a new connection for each event. This protocol overcomes the limitations of HTTP where each request must open a separate connection, making it ideal for use cases such as live sports scores, social feeds, or essentials like chat applications.

How WebSockets Work

A WebSocket starts with an HTTP request using the Upgrade header. This turns an HTTP connection into a WebSocket connection. When a client sends a WebSocket handshake request, the server responds, establishing a two-way connection.

Implementing WebSockets in Go

Go has several packages that support WebSocket creation and operation. One of the popular ones is gorilla/websocket. Let’s see an example of creating a simple WebSocket server and client using this package.

Setting Up a Go WebSocket Server

First, you’ll need to install the gorilla/websocket package:

go get github.com/gorilla/websocket

Now, let’s create a server file named server.go:

package main

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

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true  // Allow connections from any origin
    },
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer ws.Close()

    for {
        var msg string
        err := ws.ReadJSON(&msg)
        if err != nil {
            fmt.Println("Error reading json.", err)
            break
        }
        fmt.Printf("Received: %s\n", msg)
    }
}

func main() {
    http.HandleFunc("/ws", handleConnections)
    fmt.Println("WebSocket server started on :8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Printf("Error starting server: %s\n", err)
        return
    }
}

Here, we utilize the gorilla/websocket package to handle WebSocket connections, reading data from the client and capturing any errors.

Setting Up a Go WebSocket Client

Next, we’ll build a client in a file named client.go to connect and communicate with our server:

package main

import (
    "fmt"
    "os"
    "github.com/gorilla/websocket"
)

func main() {
    var addr = "localhost:8080"
    u := "ws://" + addr + "/ws"

    c, _, err := websocket.DefaultDialer.Dial(u, nil)
    if err != nil {
        fmt.Printf("dialError: %s\n", err)
        os.Exit(1)
    }
    defer c.Close()

    for {
        var msg string
        if err := c.WriteJSON("Hello, server!"); err != nil {
            fmt.Printf("writeError: %s\n", err)
            return
        }
        if err := c.ReadJSON(&msg); err != nil {
            fmt.Printf("readError: %s\n", err)
            return
        }
        fmt.Printf("Server reply: %s\n", msg)
    }
}

This client connects to the WebSocket server and sends a greeting, demonstrating a simplistic messaging functionality.

Closing Thoughts

By harnessing WebSocket’s full-duplex capabilities with Go’s robust toolset, developers can build real-time applications that offer seamless, high-performing user interactions. Understanding WebSocket protocols and implementing effective upgrades are critical steps in bringing your application to life.

Next Article: Implementing a Real-Time Chat Application Using WebSockets in Go

Previous Article: How to Create a WebSocket Client in Go

Series: Websocket & Chat Programs in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant