การดู : 0

12/04/2026 18:16น.

EP.113 การสร้างระบบ Chat Multi-room ขั้นสูง (Advanced Multi-room Chat System)

EP.113 การสร้างระบบ Chat Multi-room ขั้นสูง (Advanced Multi-room Chat System)

#Golang The Series

#redis pubsub

#Multi-room Chat

#WebSocket

#Go

ในระบบแชทแบบเรียลไทม์ทั่วไป ผู้ใช้มักสามารถพูดคุยกันได้ใน "ห้องเดียว" เท่านั้น แต่เมื่อระบบเติบโต เช่น การสนทนาในทีม, ห้อง Support, ห้องเล่นเกม หรือกลุ่มลูกค้า เราต้องออกแบบให้ระบบรองรับ “หลายห้อง (Multi-room)” พร้อมการควบคุมแยกกันชัดเจน

 

EP นี้จะพาคุณเรียนรู้การสร้างระบบแชทที่รองรับหลายห้อง พร้อมฟีเจอร์ระดับ production เช่น:

  • การกระจายข้อความ (Broadcast)
  • การจัดการสมาชิกในแต่ละห้อง
  • การสื่อสารข้ามเครื่อง (multi-instance) ด้วย Redis Pub/Sub

 

🧩 โครงสร้างระบบ Chat หลายห้อง

 

Client → WebSocket Gateway → Redis Pub/Sub → Chat Rooms

 

องค์ประกอบหลัก:

  • Room Manager: จัดการห้องทั้งหมด (สร้าง, ลบ, ตรวจสอบสมาชิก)
  • Connection Manager: จัดการการเชื่อมต่อของผู้ใช้ในแต่ละห้อง
  • Redis Pub/Sub: ใช้กระจายข้อความข้าม instance

 

⚙️ โครงสร้างข้อมูลพื้นฐาน

 

type Client struct {
	ID     string
	Conn   *websocket.Conn
	RoomID string
}

type Room struct {
	ID      string
	Clients map[*Client]bool
}

 

สร้างตัวจัดการห้อง:

type RoomManager struct {
	Rooms map[string]*Room
	mu    sync.Mutex
}

func NewRoomManager() *RoomManager {
	return &RoomManager{
		Rooms: make(map[string]*Room),
	}
}

 

💡 ฟังก์ชันจัดการห้องและสมาชิก

 

func (rm *RoomManager) JoinRoom(roomID string, client *Client) {
	rm.mu.Lock()
	defer rm.mu.Unlock()

	room, ok := rm.Rooms[roomID]
	if !ok {
		room = &Room{ID: roomID, Clients: make(map[*Client]bool)}
		rm.Rooms[roomID] = room
	}

	room.Clients[client] = true
	client.RoomID = roomID
}

func (rm *RoomManager) LeaveRoom(roomID string, client *Client) {
	rm.mu.Lock()
	defer rm.mu.Unlock()

	if room, ok := rm.Rooms[roomID]; ok {
		delete(room.Clients, client)
		if len(room.Clients) == 0 {
			delete(rm.Rooms, roomID)
		}
	}
}

 

✅ หากผู้ใช้เข้าห้อง ระบบจะตรวจสอบห้องนั้น — หากยังไม่มีจะสร้างให้ทันที

 

📡 การ Broadcast ข้อความภายในห้อง

 

func (rm *RoomManager) Broadcast(roomID string, msg string) {
	rm.mu.Lock()
	defer rm.mu.Unlock()

	if room, ok := rm.Rooms[roomID]; ok {
		for c := range room.Clients {
			c.Conn.WriteMessage(websocket.TextMessage, []byte(msg))
		}
	}
}

 

✅ ผู้ใช้ทุกคนในห้องจะได้รับข้อความพร้อมกันแบบเรียลไทม์

 

🔄 การขยายระบบด้วย Redis Pub/Sub

 

หากระบบมีหลาย instance การ broadcast ต้องใช้ Redis Pub/Sub:

func subscribeRedis(rm *RoomManager, rdb *redis.Client) {
	sub := rdb.Subscribe(context.Background(), "chat_channel")
	for msg := range sub.Channel() {
		var data struct {
			RoomID  string `json:"room_id"`
			Message string `json:"message"`
		}
		json.Unmarshal([]byte(msg.Payload), &data)
		rm.Broadcast(data.RoomID, data.Message)
	}
}

func publishMessage(rdb *redis.Client, roomID, msg string) {
	data, _ := json.Marshal(map[string]string{
		"room_id": roomID,
		"message": msg,
	})
	rdb.Publish(context.Background(), "chat_channel", data)
}

 

✅ ไม่ว่า client จะเชื่อมกับเครื่องไหน ข้อความก็ถึงทุกคนทันที!

 

🧠 เทคนิคเพิ่มประสิทธิภาพ

 

หมวดแนวทาง
Scalabilityใช้ Redis หรือ NATS สำหรับกระจายข้อความ
Room Typeแยกประเภทห้อง เช่น global, private, team
User Managementเก็บข้อมูลผู้ใช้ต่อห้องใน Redis hash
Persistenceเก็บ message ลงฐานข้อมูลเพื่อดูย้อนหลัง
Monitoringติดตาม metric เช่น จำนวน connection ต่อห้อง

 

🚀 ท้าให้ลอง!

 

ลองสร้างระบบ Chat หลายห้องด้วย Go + WebSocket ต่อ Redis เพื่อรองรับการทำงานแบบกระจาย (Distributed System)

ถ้าคุณทำได้ นี่คือโครงสร้างระดับ Enterprise Chat ที่ใช้ได้จริงใน Production ✅

 


 

🌟 Next EP: EP.114 การจัดการ Multi-device & Multi-session

 

ใน EP.114 เราจะเข้าสู่โลกของการออนไลน์พร้อมกันหลายอุปกรณ์ของผู้ใช้เดียวกัน เรียนรู้การออกแบบ Session, ป้องกันซ้ำซ้อน, และรองรับ Mobile/Desktop ได้พร้อมกัน แบบเสถียร ปลอดภัย และใช้ได้จริงบน WebSocket! 📱💻