การดู : 0

12/04/2026 18:18น.

Ep.31 Go กับ Event-Driven WebSocket - เพิ่มความยืดหยุ่น

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 เพื่อรองรับระบบขนาดใหญ่และแยกการทำงานออกเป็นส่วนๆ ครับ!