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/websocketCreating 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.goEnsure 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.