End of Life for Twilio Programmable Video - Upgrade to VideoSDKLearn More

How to Use Gorilla WebSocket to Build Real-time Web Apps?

Learn how to use Gorilla WebSocket to build robust and efficient real-time web applications in Go.

Introduction to Gorilla WebSocket

In today's digital landscape, real-time communication is essential for creating dynamic and interactive web applications. One of the most effective tools for achieving this is the WebSocket protocol, which facilitates full-duplex communication channels over a single TCP connection. Among the various libraries available for implementing WebSocket in Go, Gorilla WebSocket stands out due to its simplicity, efficiency, and robustness.

What is Gorilla Websocket?

Gorilla WebSocket is a Go library designed for handling WebSocket connections with ease. It provides a comprehensive set of features for building real-time web applications, making it a popular choice among developers. Applications such as chat systems, live notifications, and real-time data updates rely heavily on WebSocket for seamless performance, and Gorilla WebSocket is often the go-to library for these use cases.
By leveraging the power of Gorilla WebSocket, developers can create scalable and efficient real-time applications with minimal hassle. Whether you're building a simple chat application or a complex real-time data dashboard, Gorilla WebSocket offers the tools and flexibility needed to bring your ideas to life.
We will walk you through creating a basic WebSocket server and client, managing connections, broadcasting messages, handling errors, and optimizing performance. Additionally, we will explore best practices for security and performance to ensure your applications run smoothly and securely.

Getting Started with Gorilla WebSocket

Gorilla WebSocket is a powerful library for building real-time applications in Go. It simplifies the process of handling WebSocket connections and is known for its performance and reliability. Before diving into coding, ensure you have a basic understanding of Go and the WebSocket protocol. This will help you grasp the concepts more effectively.

Why choose Gorilla WebSocket?

It offers extensive features, a well-maintained codebase, and comprehensive documentation. Whether you are building chat applications, live updates, or notifications, Gorilla WebSocket is a dependable choice.

Pre-requisites

  • Basic knowledge of Go programming.
  • Understanding of the WebSocket protocol.
  • Go environment set up on your system.

Setting Up Your Development Environment

Before you can start using Gorilla WebSocket, you need to set up your development environment. Here’s how to do it:

Install Go

Download and install the latest version of Go from the

official website

.

Set up your Go workspace

Create a directory for your Go projects and set the GOPATH environment variable.

Install Gorilla WebSocket

Open your terminal and run:

bash

1   go get github.com/gorilla/websocket
This command will download and install the Gorilla WebSocket package.

Project Structure

Create a new directory for your project and organize it as follows:
1   mywebsocketapp/
2     ├── main.go

Creating Your First WebSocket Server

Let's create a basic WebSocket server using Gorilla WebSocket. Open your main.go file and add the following code:

go

1package main
2
3import (
4    "fmt"
5    "net/http"
6    "github.com/gorilla/websocket"
7)
8
9var upgrader = websocket.Upgrader{
10    ReadBufferSize:  1024,
11    WriteBufferSize: 1024,
12}
13
14func handler(w http.ResponseWriter, r *http.Request) {
15    conn, err := upgrader.Upgrade(w, r, nil)
16    if err != nil {
17        fmt.Println(err)
18        return
19    }
20    defer conn.Close()
21
22    for {
23        messageType, p, err := conn.ReadMessage()
24        if err != nil {
25            fmt.Println(err)
26            return
27        }
28        if err := conn.WriteMessage(messageType, p); err != nil {
29            fmt.Println(err)
30            return
31        }
32    }
33}
34
35func main() {
36    http.HandleFunc("/", handler)
37    http.ListenAndServe(":8080", nil)
38}

Explanation

  • Upgrader: This upgrades the HTTP connection to a WebSocket connection.
  • Handler: Manages the WebSocket connection, reading messages from the client and echoing them back.
  • Main: Sets up the HTTP server on port 8080 and maps the handler function to the root URL.

Creating a WebSocket Client

To interact with our WebSocket server, we need a client. Here’s how you can create one:

HTML File

Create an index.html file in your project directory:

HTML

1   <!DOCTYPE html>
2   <html>
3   <head>
4       <title>WebSocket Client</title>
5   </head>
6   <body>
7       <script>
8           const socket = new WebSocket('ws://localhost:8080/');
9
10           socket.onopen = () => {
11               console.log('Connected to server');
12               socket.send('Hello Server!');
13           };
14
15           socket.onmessage = (event) => {
16               console.log('Message from server: ', event.data);
17           };
18
19           socket.onclose = () => {
20               console.log('Disconnected from server');
21           };
22       </script>
23   </body>
24   </html>

Explanation

  • WebSocket: Establishes a WebSocket connection to the server.
  • onopen: Sends a message to the server upon connection.
  • onmessage: Receives messages from the server.
  • onclose: Logs when the connection is closed.

Handling WebSocket Connections

Managing WebSocket connections efficiently is crucial for real-time applications. Gorilla WebSocket makes it easy to handle multiple connections. Here’s an example:

go

1var clients = make(map[*websocket.Conn]bool)
2
3func handler(w http.ResponseWriter, r *http.Request) {
4    conn, err := upgrader.Upgrade(w, r, nil)
5    if err != nil {
6        fmt.Println(err)
7        return
8    }
9    defer conn.Close()
10    clients[conn] = true
11
12    for {
13        messageType, p, err := conn.ReadMessage()
14        if err != nil {
15            delete(clients, conn)
16            fmt.Println(err)
17            return
18        }
19        for client := range clients {
20            if err := client.WriteMessage(messageType, p); err != nil {
21                fmt.Println(err)
22                return
23            }
24        }
25    }
26}

Explanation

  • Clients Map: Keeps track of all connected clients.
  • Broadcast Loop: Sends messages to all connected clients.

Broadcasting Messages to Clients

Broadcasting messages is essential for many real-time applications. Here’s how to implement it:

go

1func broadcast(messageType int, message []byte) {
2    for client := range clients {
3        if err := client.WriteMessage(messageType, message); err != nil {
4            client.Close()
5            delete(clients, client)
6        }
7    }
8}
In the handler function, call broadcast instead of writing to each client directly:

go

1func handler(w http.ResponseWriter, r *http.Request) {
2    // ...existing code...
3    broadcast(messageType, p)
4}

Explanation

  • broadcast Function: Iterates over all clients and sends the message.

Error Handling in Gorilla WebSocket

Proper error handling ensures your WebSocket application is robust and reliable. Here’s a basic example:

go

1func handler(w http.ResponseWriter, r *http.Request) {
2    conn, err := upgrader.Upgrade(w, r, nil)
3    if err != nil {
4        http.Error(w, "Could not upgrade to WebSocket", http.StatusBadRequest)
5        return
6    }
7    defer conn.Close()
8
9    for {
10        _, _, err := conn.ReadMessage()
11        if err != nil {
12            if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
13                fmt.Printf("Unexpected close error: %v\n", err)
14            }
15            break
16        }
17    }
18}

Advanced Features of Gorilla WebSocket

Gorilla WebSocket supports advanced features like authentication and message filtering:

Authentication

go

1   func handler(w http.ResponseWriter, r *http.Request) {
2       // Add your authentication logic here
3       authorized := authenticate(r)
4       if !authorized {
5           http.Error(w, "Unauthorized", http.StatusUnauthorized)
6           return
7       }
8       // ...existing code...
9   }

Message Filtering

go

1   func handler(w http.ResponseWriter, r *http.Request) {
2       // ...existing code...
3       for {
4           messageType, message, err := conn.ReadMessage()
5           if err != nil {
6               // ...existing error handling...
7           }
8           if isValidMessage(message) {
9               broadcast(messageType, message)
10           }
11       }
12   }

Explanation

  • Authentication: Validates user before establishing a WebSocket connection.
  • Message Filtering: Ensures only valid messages are broadcasted.

Get Free 10,000 Minutes Every Months

No credit card required to start.

Performance Optimization of WebSocket

Optimizing WebSocket performance is critical for handling high traffic:

Resource Management

  • Close idle connections to free up resources.
  • Use buffered channels for handling high message throughput.

Monitoring

  • Implement logging and monitoring to track performance metrics.
  • Use tools like Prometheus and Grafana for real-time monitoring.

Scaling

  • Deploy multiple WebSocket servers behind a load balancer.
  • Use Kubernetes for auto-scaling based on traffic.

Best Practices

  • Regularly review and optimize your code.
  • Test under various load conditions to identify bottlenecks.

WebSocket Security

Ensuring the security of your WebSocket connections is paramount:

Secure WebSocket (WSS)

go

1   err := http.ListenAndServeTLS(":8080", "cert.pem", "key.pem", nil)

Origin Checking

go

1   upgrader.CheckOrigin = func(r *http.Request) bool {
2       return r.Header.Get("Origin") == "https://yourdomain.com"
3   }

Rate Limiting

Implement rate limiting to prevent abuse:

go

1   func rateLimit(next http.Handler) http.Handler {
2       return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3           if !allowRequest(r) {
4               http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
5               return
6           }
7           next.ServeHTTP(w, r)
8       })
9   }

Common Pitfalls

  • Avoid exposing sensitive information over WebSocket.
  • Regularly update dependencies to patch vulnerabilities.

Conclusion

In this article, we've explored the fundamentals of using Gorilla WebSocket to build real-time web applications. From setting up your development environment to creating a WebSocket server and client, managing connections, broadcasting messages, and implementing advanced features, Gorilla WebSocket offers a robust and flexible solution for developers.
Additionally, we covered performance optimization and security best practices to ensure your applications are both efficient and secure. By following these guidelines and examples, you can confidently develop scalable and reliable real-time applications using Gorilla WebSocket.

Want to level-up your learning? Subscribe now

Subscribe to our newsletter for more tech based insights

FAQ