12/04/2026 18:18น.

Ep.31 Go กับ Event-Driven WebSocket - เพิ่มความยืดหยุ่น
#Event-Driven Architecture
#WebSocket
#Event-Driven
#การพัฒนาระบบ
#Server
#การออกแบบระบบ
#ความยืดหยุ่น
#การปรับขนาด
#Golang
#ภาษา Go
#การพัฒนาโปรแกรม
#การศึกษาการเขียนโปรแกรม
#การเขียนโปรแกรม
#การเขียนโปรแกรม Go
#การเขียนโปรแกรมสำหรับมือใหม่
#ฝึกเขียนโปรแกรม
#พัฒนาโปรแกรม
#ภาษาโปรแกรม
#ภาษาโปรแกรมมิ่ง
#โปรแกรมเมอร์
#Superdev School
Go กับ Event-Driven WebSocket - เพิ่มความยืดหยุ่น
ใน EP นี้ เราจะมาทำความรู้จักกับ Event-Driven Architecture และวิธีปรับ WebSocket Server ให้รองรับการทำงานแบบ Event-Driven ซึ่งช่วยให้ระบบของคุณยืดหยุ่นและปรับขนาดได้ง่ายขึ้นครับ!
Event-Driven Architecture คืออะไร?
Event-Driven Architecture คือรูปแบบการออกแบบระบบที่ทำงานโดยการส่งและตอบสนองต่อเหตุการณ์ (Events) เช่น การกดปุ่ม, การเชื่อมต่อใหม่ หรือการส่งข้อความ
ข้อดีของ Event-Driven Architecture :
- ยืดหยุ่น : สามารถเพิ่มฟีเจอร์ใหม่ได้โดยไม่กระทบกับส่วนอื่นของระบบ
- รองรับการปรับขนาด : การแยกการทำงานออกเป็น Event ช่วยลดการประมวลผลที่ซ้ำซ้อน
- เหมาะสำหรับ WebSocket : ช่วยจัดการการสื่อสารแบบเรียลไทม์ได้ดีขึ้น
- การนำ Event-Driven มาใช้ใน WebSocket
ใน WebSocket Server เราสามารถใช้ Event-Driven ได้โดยการ :
- แยกการทำงานตาม Event เช่น onConnect, onMessage, onDisconnect
- ใช้ Event Bus หรือ Pub/Sub สำหรับกระจาย Event ภายในระบบ
- เพิ่ม Handler สำหรับจัดการแต่ละ Event
ตัวอย่างการทำงานแบบ Event-Driven บน WebSocket
1. กำหนดโครงสร้างของ Event
Name : ชื่อ Event (เช่น message, disconnect)
Data : ข้อมูลที่เกี่ยวข้องกับ Event
type Event struct {
Name string `json:"name"`
Data interface{} `json:"data"`
}
2. สร้าง Event Dispatcher
Register : ลงทะเบียน Event และ Handler
Dispatch : กระจาย Event ไปยัง Handler ที่ลงทะเบียนไว้
package main
import "sync"
type EventHandler func(data interface{})
type EventDispatcher struct {
handlers map[string][]EventHandler
mu sync.RWMutex
}
func NewEventDispatcher() *EventDispatcher {
return &EventDispatcher{handlers: make(map[string][]EventHandler)}
}
func (d *EventDispatcher) Register(event string, handler EventHandler) {
d.mu.Lock()
defer d.mu.Unlock()
d.handlers[event] = append(d.handlers[event], handler)
}
func (d *EventDispatcher) Dispatch(event string, data interface{}) {
d.mu.RLock()
defer d.mu.RUnlock()
if handlers, found := d.handlers[event]; found {
for _, handler := range handlers {
go handler(data) // เรียกใช้ Handler แบบ Concurrent
}
}
}
3. ใช้งาน Event Dispatcher ใน WebSocket
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
var dispatcher = NewEventDispatcher()
func handleConnections(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Error upgrading connection:", err)
return
}
defer conn.Close()
dispatcher.Dispatch("connect", conn)
for {
_, msg, err := conn.ReadMessage()
if err != nil {
log.Println("Error reading message:", err)
dispatcher.Dispatch("disconnect", conn)
break
}
var event Event
if err := json.Unmarshal(msg, &event); err != nil {
log.Println("Error unmarshaling event:", err)
continue
}
dispatcher.Dispatch(event.Name, event.Data)
}
}
func main() {
dispatcher.Register("connect", func(data interface{}) {
conn := data.(*websocket.Conn)
log.Println("New client connected:", conn.RemoteAddr())
})
dispatcher.Register("message", func(data interface{}) {
log.Printf("Message received: %v", data)
})
dispatcher.Register("disconnect", func(data interface{}) {
conn := data.(*websocket.Conn)
log.Println("Client disconnected:", conn.RemoteAddr())
})
http.HandleFunc("/ws", handleConnections)
log.Println("WebSocket server started at :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
อธิบายโค้ด
- EventDispatcher : จัดการ Event และกระจายไปยัง Handler ที่เกี่ยวข้อง
- Register : ลงทะเบียน Event เช่น connect, message, disconnect
- Dispatch : เรียกใช้ Handler ที่เกี่ยวข้องเมื่อเกิด Event
- onConnect : จัดการเมื่อผู้ใช้เชื่อมต่อ
- onMessage : จัดการข้อความที่ได้รับ
- onDisconnect : จัดการเมื่อผู้ใช้ตัดการเชื่อมต่อ
ปรับปรุงเพิ่มเติม
- ใช้ Redis Pub/Sub : สำหรับกระจาย Event ระหว่าง WebSocket Server หลายตัว
- เพิ่ม Middleware : สำหรับตรวจสอบสิทธิ์ก่อน Dispatch Event
- เพิ่ม Event Queue : ใช้ RabbitMQ หรือ Kafka เพื่อรองรับการจัดการ Event ขนาดใหญ่
สรุปง่ายๆ
- การทำงานแบบ Event-Driven ช่วยเพิ่มความยืดหยุ่นและปรับขนาดได้ง่าย
- ใช้ Event Dispatcher เพื่อจัดการ Event ภายใน WebSocket Server
- รองรับการเพิ่มฟีเจอร์ใหม่โดยไม่กระทบกับส่วนอื่นของระบบ
กิจกรรมสนุกๆ
ลองสร้างระบบแชทแบบเรียลไทม์ที่ใช้ Event-Driven โดยมี Event เช่น joinRoom, sendMessage, และ leaveRoom แล้วเพิ่มฟีเจอร์ให้สามารถ Broadcast ข้อความไปยังทุกคนในห้องได้!
ใน EP ถัดไป เราจะพูดถึง การเชื่อมต่อ WebSocket กับ Microservices เพื่อรองรับระบบขนาดใหญ่และแยกการทำงานออกเป็นส่วนๆ ครับ!