Sling Academy
Home/Golang/How to Create a WebSocket Client in Go

How to Create a WebSocket Client in Go

Last updated: November 26, 2024

WebSockets allow you to open an interactive communication session between a user's browser and a server. In this article, we'll guide you through creating a WebSocket client in Go, a language known for its performance and efficiency in network programming.

Setting Up Your Go Environment

Before we start coding, ensure you have Go installed on your machine. You can download it from the official website and follow the installation instructions for your operating system.

Adding the WebSocket Package

For WebSockets support, we will use the Gorilla's WebSocket package. You can add it to your project by running the following:

go get -u github.com/gorilla/websocket

Creating a WebSocket Client

Let's create a simple WebSocket client that connects to a WebSocket server, sends a message, and receives responses. Here’s the complete code:


package main

import (
    "fmt"
    "log"
    "net/url"
    "os"
    "os/signal"
    "time"
    "github.com/gorilla/websocket"
)

func main() {
    // Define the WebSocket server URL 
    serverURL := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/echo"}
    log.Printf("connecting to %s\n", serverURL.String())

    // Connect to the WebSocket server
    conn, _, err := websocket.DefaultDialer.Dial(serverURL.String(), nil)
    if err != nil {
        log.Fatal("dial:", err)
    }
    defer conn.Close()

    // Listen for interrupt signals to close the connection properly
    interrupt := make(chan os.Signal, 1)
    signal.Notify(interrupt, os.Interrupt)

    // Writer routine to send messages
    done := make(chan struct{})
    go func() {
        defer close(done)
        for {
            _, message, err := conn.ReadMessage()
            if err != nil {
                log.Println("read:", err)
                return
            }
            log.Printf("received: %s\n", message)
        }
    }()

    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()

    for {
        select {
        case <-done:
            return
        case t := <-ticker.C:
            err := conn.WriteMessage(websocket.TextMessage, []byte(t.String()))
            if err != nil {
                log.Println("write:", err)
                return
            }
        case <-interrupt:
            log.Println("interrupt")

            // Cleanly close the connection by sending a close message
            err := conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
            if err != nil {
                log.Println("write close:", err)
                return
            }
            select {
            case <-done:
            case <-time.After(time.Second):
            }
            return
        }
    }
}

Understanding the Code

  • Connection: We create a connection to the WebSocket server using websocket.DefaultDialer.Dial.
  • Message Handling: We have a separate goroutine that reads and logs messages coming in from the server.
  • Sending Messages: Messages are sent to the server every second using a time.Ticker.
  • Graceful Shutdown: We listen for OS interrupt signals (such as Ctrl+C), and handle cleanup by closing the WebSocket connection properly.

Running the Client

Save the above code to a file client.go and execute it with:

go run client.go

Ensure you have a WebSocket server running on localhost:8080 to test the client. You may replace the URL with any valid WebSocket server to test the client connectivity.

Conclusion

We've walked through constructing a WebSocket client in Go, learning how to connect, send and receive messages while handling signals for interruptions. Utilizing Go’s concurrency primitives in combination with the Gorilla WebSocket package makes this both an efficient and effective choice for WebSocket programming.

Next Article: Understanding WebSocket Protocols and Upgrades in Go

Previous Article: Building a Simple WebSocket Server 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