WebSockets allow your frontend and backend to talk instantly, without the old HTTP request/response delay. In this tutorial, we'll show you how to build a real-time chat application using Go on the backend and JavaScript on the frontend.
🚀 This is Part 3 of the WebSocket series. If you're just joining:
Let’s put all of it to work now.
Project Overview
We’re building a very basic chat room where users can:
- Send messages using a frontend form
- Receive messages instantly from other users via WebSocket
Tech stack:
- Go (Golang) + Gorilla WebSocket backend
- HTML + JavaScript frontend
Backend Setup (Recap)
Here’s the Go server we used in Part 2:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
// Allow all connections
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 {
log.Println("Upgrade error:", err)
return
}
defer conn.Close()
for {
messageType, msg, err := conn.ReadMessage()
if err != nil {
log.Println("Read error:", err)
break
}
log.Printf("Received: %s\n", msg)
// Echo message back to client
if err := conn.WriteMessage(messageType, msg); err != nil {
log.Println("Write error:", err)
break
}
}
}
func main() {
http.HandleFunc("/ws", handleWebSocket)
fmt.Println("Server started at http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
This server listens for incoming WebSocket connections at /ws
, upgrades the HTTP connection, and echoes back any message it receives.
Frontend Code (HTML + JavaScript)
Here’s a minimal frontend you can save as index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Go WebSocket Chat</title>
<style>
body { font-family: sans-serif; padding: 2rem; }
#messages { border: 1px solid #ccc; height: 300px; overflow-y: scroll; margin-bottom: 1rem; padding: 1rem; }
</style>
</head>
<body>
<h2>Chat</h2>
<div id="messages"></div>
<input type="text" id="msgInput" placeholder="Type a message...">
<button onclick="sendMessage()">Send</button>
<script>
const ws = new WebSocket("ws://localhost:8080/ws");
const messagesDiv = document.getElementById("messages");
ws.onmessage = (event) => {
const msg = document.createElement("div");
msg.textContent = event.data;
messagesDiv.appendChild(msg);
};
function sendMessage() {
const input = document.getElementById("msgInput");
ws.send(input.value);
input.value = "";
}
</script>
</body>
</html>
How It Works
- The browser opens a WebSocket connection to
ws://localhost:8080/ws
- When you type and click Send, JavaScript sends the message to the Go backend.
- The Go server receives it and immediately echoes it back.
- JavaScript listens for incoming messages and displays them.
It's a direct two-way pipeline — no reloading, no polling!
Debugging Tips
- Browser Console Errors: Open DevTools (F12) to see if WebSocket failed to connect.
- CORS Issues? Make sure your WebSocket server is on the same origin or add CORS headers.
- Connection refused? Ensure your server is running on the right port.
Possibilities Beyond Chat
Now that you’ve got WebSockets working, here’s what else you can build:
- ✅ Real-time notifications
- ✅ Multiplayer games
- ✅ Live dashboards
- ✅ Collaborative editors (like Google Docs)
And with more tools:
- 🔐 Add authentication with JWT
- 🔁 Handle reconnects with backoff
- ⚙️ Scale using Redis pub/sub or message queues
Where We End
This wraps up our 3-part WebSocket series:
- HTTP vs WebSockets: Why it matters
- Building a WebSocket server in Go
- Connecting that server to a live frontend
From here, you're ready to explore more advanced designs:
- Broadcasting to many clients
- Creating chat rooms
- Scaling with channels and goroutines
Let me know in the comments what you're building with Go and WebSockets 👇
Top comments (0)