Introduction
Websockets in Go is simple and easy to apply. It means It is fun and effortless to apply it using standard packages or third-party packages (e.g. gorilla websockets). Let us first learn about websockets in general, their use cases, and then how to implement them in Go.
What is a websocket?
A WebSocket is a communication protocol that provides full-duplex communication channels over a single TCP connection. It allows for real-time, two-way communication between a client (typically a web browser) and a server. Unlike traditional HTTP, which is request-response-based and stateless, WebSocket connections remain open, enabling continuous data exchange in both directions without the need to re-establish the connection for each message.
Prerequisites
- Learn Go
- Install Go
Use-cases of Websockets
WebSockets serve as a go-to solution for applications demanding swift, real-time communication, including:
- Online Chat Platforms
- Online Gaming Interfaces
- Financial Trading Platforms
- Live Sports Updates
- Collaborative Tools
Their utilization presents advantages over traditional polling or long-polling methods. WebSockets circumvent the inefficiency of repeatedly initiating connections for each request. This approach diminishes the overhead linked with real-time updates, ensuring faster and more responsive communication channels.
How it works?
To establish a WebSocket connection, a client sends an initial HTTP request with an “Upgrade” header to indicate its intention to switch to the WebSocket protocol. Once the server agrees to the upgrade, the connection is switched to a full-duplex WebSocket connection, and both the client and server can send messages to each other anytime.
Implementation of Websockets in go
Step 1 – Server-side implementation of Websockets in go
package main
import (
"net/http"
"github.com/gorilla/websocket"
)
// since websockets are fully duplex connections so we can customise
// buffer size for receive side (ReadBufferSize) and buffer size for send
// side (WriteBufferSize). It is in bytes
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func handleWebSocketConnection(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}
defer conn.Close() // closing the connection is must otherwise it will cause memory leak
for {
messageType, p, err := conn.ReadMessage() // read from client
if err != nil {
return
}
fmt.Println("Message received from client: ", string(p))
reply := "from server: " + string(p)
if err := conn.WriteMessage(messageType, []byte(reply)); err != nil { // send to client
return
}
}
}
func main() {
http.HandleFunc("/ws", handleWebSocketConnection)
fmt.Println("Starting websocket server on 8080")
http.ListenAndServe(":8080", nil)
}
Step 2 – Client-side implementation
package main
import (
"log"
"github.com/gorilla/websocket"
)
func main() {
conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
message := []byte("Hello, WebSocket!")
// WriteMessage will write the message to the connection which will be received
// by server using conn.ReadMessage()
if err := conn.WriteMessage(websocket.TextMessage, message); err != nil {
log.Fatal(err)
}
// ReadMessage will read the message from the connection which was sent
// by server using conn.WriteMessage()
_, p, err := conn.ReadMessage()
if err != nil {
log.Fatal(err)
}
log.Printf("Received: %s", p)
}
Step 3 – Project Setup
cd to /path/to/workspace. E.g cd ~/workspace/go
Create client and server directory
mkdir client && mkdir server
Initialize server using go mod init. cd server && go mod init websocketserver
Create main.go in server and write server-side code from above
Initialize client using go mod init. cd client && go mod init websocketclient
Create main.go in client and write client-side code from above
Step 4 – Execution
cd server (go inside server directory)
go run main.go (this will pull dependencies, build and run)
Open another terminal
cd client (go inside client directory)
go run main.go (this will pull dependencies, build and run)
Output
// Client Side
Hello, WebSocket!
from server: Hello, WebSocket!
// Server Side
Starting websocket server on 8080
Message received from client: Hello, WebSocket!
Conclusion
In conclusion, WebSockets in Go presents an instrumental technology for building robust, real-time communication channels. Leveraging Go’s native support for WebSockets, developers can craft efficient and responsive applications across various domains. The versatility of WebSockets extends to powering online gaming, chat platforms, financial trading systems, live sports updates, and collaborative tools.
The inherent advantages of WebSockets, including low-latency communication and bidirectional data flow, significantly enhance the user experience in interactive applications. Go’s concurrency model further amplifies these benefits by allowing seamless integration of WebSockets with concurrent operations, ensuring scalable and efficient systems.
WebSockets’ capability to maintain persistent connections, eliminate the overhead of connection establishment for each request, and enable real-time updates solidifies their place as a cornerstone for modern, responsive web applications. Embracing WebSockets in Go not only facilitates responsive and engaging user experiences but also contributes to building high-performing and interactive applications.
Enjoy!!!