Creating a WebSocket Server in Go with Gorilla
WebSockets are a powerful way to enable real-time communication between a server and a client. They keep a connection open, allowing messages to be sent back and forth efficiently. In this blog post, we'll build a WebSocket server using Go and the popular Gorilla WebSocket library.
Table of Contents
- Introduction to WebSockets and Gorilla
- Setting Up the Project
- Folder Structure
- Installing Gorilla WebSocket
- Creating the WebSocket Server
- Handling Messages
- Running the Application
- Conclusion
- GitHub Repository
Introduction to WebSockets and Gorilla
WebSockets are used for real-time, full-duplex communication between a client and a server. Unlike HTTP, WebSockets allow for continuous data exchange without needing to repeatedly open and close connections.
The Gorilla WebSocket package makes it easy to implement WebSockets in Go. It handles the WebSocket handshake, message reading/writing, and connection management efficiently.
Setting Up the Project
Let’s set up a simple project to demonstrate WebSocket functionality. This project will include:
- A WebSocket server that accepts connections.
- A client that communicates with the server.
Folder Structure
Here's the folder structure for our project:
websocket-server/
├── main.go # Entry point of the application
├── handlers/ # Contains WebSocket handlers
│ └── websocket.go # Handles WebSocket connections and messages
├── static/ # Contains client-side HTML/JS files
│ └── index.html # A simple client interface
└── go.mod # Go module file
Installing Gorilla WebSocket
First, we need to install the Gorilla WebSocket package. Run the following command in your terminal:
go get -u github.com/gorilla/websocket
This will add the Gorilla WebSocket library to your project.
Creating the WebSocket Server
Step 1: Write the main.go
Create a main.go
file in the root of your project:
package main
import (
"fmt"
"log"
"net/http"
"websocket-server/handlers"
)
func main() {
http.HandleFunc("/ws", handlers.HandleWebSocket)
fs := http.FileServer(http.Dir("./static"))
http.Handle("/", fs)
port := ":8080"
fmt.Printf("Server is running on http://localhost%s\n", port)
log.Fatal(http.ListenAndServe(port, nil))
}
This code sets up an HTTP server, serves static files from the static
folder, and handles WebSocket connections at the /ws
endpoint.
Step 2: Write the WebSocket Handler
In the handlers
folder, create a file named websocket.go
:
package handlers
import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func HandleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println("Failed to upgrade connection:", err)
return
}
defer conn.Close()
fmt.Println("Client connected")
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
fmt.Println("Read error:", err)
break
}
fmt.Printf("Received: %s\n", message)
if err := conn.WriteMessage(messageType, message); err != nil {
fmt.Println("Write error:", err)
break
}
}
}
This handler upgrades the HTTP connection to a WebSocket connection, reads messages from the client, and sends them back (echo server).
Handling Messages
The HandleWebSocket
function handles incoming messages from the client. It reads the message type and content using conn.ReadMessage()
and sends the same message back using conn.WriteMessage()
.
You can extend this functionality to include broadcasting, storing messages, or handling specific commands.
Running the Application
Step 1: Create a Simple Client
In the static
folder, create an index.html
file:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Client</title>
</head>
<body>
<h1>WebSocket Client</h1>
<input type="text" id="messageInput" placeholder="Type a message...">
<button id="sendButton">Send</button>
<ul id="messages"></ul>
<script>
const ws = new WebSocket("ws://localhost:8080/ws");
const messageInput = document.getElementById("messageInput");
const sendButton = document.getElementById("sendButton");
const messages = document.getElementById("messages");
ws.onmessage = (event) => {
const li = document.createElement("li");
li.textContent = `Server: ${event.data}`;
messages.appendChild(li);
};
sendButton.onclick = () => {
const message = messageInput.value;
ws.send(message);
const li = document.createElement("li");
li.textContent = `You: ${message}`;
messages.appendChild(li);
messageInput.value = "";
};
</script>
</body>
</html>
This client connects to the WebSocket server, sends messages, and displays received messages.
Step 2: Run the Server
Run the following command in your terminal:
go run main.go
Open your browser and go to http://localhost:8080. You can now send and receive messages in real-time!
Conclusion
In this tutorial, we built a simple WebSocket server using Go and Gorilla WebSocket. WebSockets are an excellent choice for real-time applications like chat apps, live notifications, and gaming.
Feel free to extend this project with advanced features like authentication, message broadcasting, and persistent storage. Happy coding!
GitHub Repository
You can find the complete code for this project on GitHub: WebSocket Server in Go.
Top comments (0)