08/05/2026 06:52น.

EP.112 การสร้างระบบ Notification แบบเรียลไทม์ (Real-time Notification System)
#WebSocket Server
#real-time notifications
#Redis Pub/Sub
#Go
#WebSocket
#notification system
#Notification
ในระบบเรียลไทม์ (Real-time System) ผู้ใช้คาดหวังว่า "ทุกสิ่งต้องอัปเดตทันที" ไม่ว่าจะเป็นข้อความใหม่ คำสั่งซื้อ สถานะออเดอร์ หรือการแจ้งเตือนต่าง ๆ หนึ่งในเทคโนโลยีที่ทำให้สิ่งนี้เป็นจริงคือ WebSocket ซึ่งสามารถ “push” ข้อมูลจากฝั่ง Server ไปยัง Client โดยไม่ต้องรอให้ผู้ใช้รีเฟรช
ใน EP นี้ เราจะสร้าง Real-time Notification System ด้วย Go และ WebSocket เพื่อให้ระบบของคุณสามารถแจ้งเตือนผู้ใช้ “ทันที” เมื่อมี Event สำคัญเกิดขึ้น! 🚀
🧩 โครงสร้างของระบบ Notification แบบเรียลไทม์
Event Source → WebSocket Server → Connected Clients
- Event Source: จุดกำเนิดเหตุการณ์ เช่น การสั่งซื้อ การตอบกลับ หรือการแจ้งเตือนจากระบบอื่น
- WebSocket Server: ทำหน้าที่ส่งข้อความแจ้งเตือนไปยังผู้ใช้แบบ real-time
- Clients: รับการแจ้งเตือนและแสดงผลบน UI
✅ ระบบสามารถรองรับผู้ใช้จำนวนมากและขยายได้ด้วย Redis Pub/Sub
⚙️ ตัวอย่างการส่ง Notification ด้วย Go
package main
import (
"context"
"encoding/json"
"log"
"net/http"
"github.com/gorilla/websocket"
"github.com/redis/go-redis/v9"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
type Notification struct {
UserID string `json:"user_id"`
Title string `json:"title"`
Message string `json:"message"`
}
var (
ctx = context.Background()
rdb = redis.NewClient(&redis.Options{Addr: "localhost:6379"})
clients = make(map[*websocket.Conn]string)
)
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil)
defer conn.Close()
userID := r.URL.Query().Get("user")
clients[conn] = userID
defer delete(clients, conn)
for {
_, _, err := conn.ReadMessage()
if err != nil {
break
}
}
}
func publishNotification(n Notification) {
data, _ := json.Marshal(n)
rdb.Publish(ctx, "notifications", data)
}
func subscribeNotifications() {
sub := rdb.Subscribe(ctx, "notifications")
ch := sub.Channel()
for msg := range ch {
var n Notification
json.Unmarshal([]byte(msg.Payload), &n)
for conn, uid := range clients {
if uid == n.UserID {
conn.WriteJSON(n)
}
}
}
}
func main() {
go subscribeNotifications()
http.HandleFunc("/ws", handleWebSocket)
log.Println("🔔 WebSocket Notification Server running on :8080")
http.ListenAndServe(":8080", nil)
}
✅ เมื่อเรียก publishNotification() → ระบบจะส่งข้อความไปยัง Redis
และทุก instance ที่ subscribe จะ broadcast ข้อความไปยัง client ที่ตรงกับ UserID
📬 ตัวอย่างการส่ง Event แจ้งเตือนจากระบบอื่น
เมื่อต้องการส่งการแจ้งเตือน เช่น:
publishNotification(Notification{
UserID: "u123",
Title: "คำสั่งซื้อของคุณถูกจัดส่งแล้ว!",
Message: "Tracking number: TH123456789",
})
✅ ผู้ใช้ที่เชื่อมต่อแบบ real-time จะได้รับ Notification ทันทีบนหน้าจอ
🧠 การออกแบบ Notification ในระดับ Production
| หมวด | แนวทางการออกแบบ |
|---|---|
| Scalability | ใช้ Redis Pub/Sub หรือ Kafka สำหรับ event bus |
| Filtering | ส่งเฉพาะ event ที่เกี่ยวข้องกับผู้ใช้หรือกลุ่ม |
| Durability | บันทึก notification ลงฐานข้อมูลก่อน broadcast |
| UX | แสดง unread badge, notification history |
| Retry | ส่งซ้ำหาก client reconnect แล้วพลาดข้อความไป |
💡 เทคนิคเพิ่มประสิทธิภาพ
- ใช้ Goroutine Pool สำหรับ broadcast ปริมาณมาก
- Batch หลาย notification เพื่อลดจำนวนรอบการส่ง
- ใช้ Minified JSON เพื่อลดขนาด payload
🚀 ท้าให้ลอง!
ลองสร้าง Notification Server ด้วย Go แล้วให้ระบบอื่นยิง Event เข้ามา คุณจะเห็นว่า client ทุกคนได้รับการแจ้งเตือนแบบ เรียลไทม์ พร้อมกัน ⚡
นึกภาพว่าคุณสามารถใช้ระบบนี้ได้กับ...
- ✅ ระบบแชท
- ✅ การแจ้งสถานะคำสั่งซื้อ
- ✅ ระบบแจ้งเตือนของแอดมิน
ทั้งหมดนี้ใช้ Go เขียนได้ภายในไม่กี่บรรทัด 💬
🌟 Next EP: EP.113 การสร้างระบบ Chat Multi-room ขั้นสูง
ใน EP.113 เราจะยกระดับขึ้นอีกขั้น สู่การสร้างระบบ Chat ที่รองรับ “หลายห้องพร้อมกัน” แบบ Enterprise เรียนรู้การจัดการห้องหลายประเภท การกระจายข้อความระหว่างห้องและการใช้ Redis เพื่อควบคุม communication ได้อย่างมีประสิทธิภาพ! 💥