12/04/2026 18:17น.

EP.88 การสร้างระบบแชทรองรับหลายห้อง (Multi-room Chat Management)
#WebSocket
#Golang
#Go
#ระบบแชท
WebSocket Chat ที่ดี ไม่ใช่แค่การเปิดให้ผู้ใช้เชื่อมต่อ แต่ต้องสามารถรองรับระบบ “หลายห้องแชท” หรือ Multi-room Chat เพื่อให้ผู้ใช้สามารถแยกกลุ่ม ส่งข้อความภายในกลุ่ม และจัดการสมาชิกแต่ละห้องได้อย่างมีประสิทธิภาพ
ในบทความนี้ เราจะมาเรียนรู้การสร้างระบบ Multi-room Chat อย่างเป็นระบบด้วย Golang + WebSocket พร้อมเทคนิคจัดการสมาชิกและสื่อสารแบบเรียลไทม์อย่างปลอดภัยและมีประสิทธิภาพ
🔧 โครงสร้างหลักของระบบหลายห้อง
ระบบจะประกอบด้วย 3 องค์ประกอบหลัก:
type Client struct {
ID string
Conn *websocket.Conn
RoomID string
Send chan []byte
}
type Room struct {
ID string
Clients map[string]*Client
Broadcast chan []byte
}
type Hub struct {
Rooms map[string]*Room
Register chan *Client
Unregister chan *Client
}
Client: ตัวแทนของผู้ใช้แต่ละราย พร้อมข้อมูลการเชื่อมต่อและห้องที่เข้าร่วมRoom: ห้องแชทแต่ละห้องที่เก็บผู้ใช้และช่องสำหรับส่งข้อความ (Broadcast)Hub: ตัวกลางรวมทุกห้อง ทำหน้าที่จัดการการเข้า-ออกของสมาชิก
🧩 การลงทะเบียน/ออกจากห้องของผู้ใช้
func (h *Hub) Run() {
for {
select {
case client := <-h.Register:
room, ok := h.Rooms[client.RoomID]
if !ok {
room = &Room{
ID: client.RoomID,
Clients: make(map[string]*Client),
Broadcast: make(chan []byte),
}
h.Rooms[client.RoomID] = room
go room.Run()
}
room.Clients[client.ID] = client
case client := <-h.Unregister:
if room, ok := h.Rooms[client.RoomID]; ok {
delete(room.Clients, client.ID)
close(client.Send)
if len(room.Clients) == 0 {
delete(h.Rooms, room.ID)
}
}
}
}
}
Register: เพิ่มผู้ใช้เข้าในห้อง หากห้องยังไม่ถูกสร้าง จะสร้างห้องใหม่โดยอัตโนมัติUnregister: ลบผู้ใช้ออกจากห้อง และลบห้องหากไม่มีสมาชิกเหลือ
📢 การกระจายข้อความภายในห้อง
func (r *Room) Run() {
for {
select {
case message := <-r.Broadcast:
for _, client := range r.Clients {
select {
case client.Send <- message:
default:
close(client.Send)
delete(r.Clients, client.ID)
}
}
}
}
}
- ข้อความใดที่ถูกส่งเข้ามาใน
Broadcastจะถูกกระจายไปยังสมาชิกในห้องนั้นทันที - หากส่งไม่ทัน จะปิดช่องสื่อสารของ client เพื่อลดการค้าง
🔄 การรับ/ส่งข้อความของแต่ละ Client
func (c *Client) ReadPump(h *Hub) {
defer func() {
h.Unregister <- c
c.Conn.Close()
}()
for {
_, msg, err := c.Conn.ReadMessage()
if err != nil {
break
}
if room, ok := h.Rooms[c.RoomID]; ok {
room.Broadcast <- msg
}
}
}
func (c *Client) WritePump() {
for msg := range c.Send {
c.Conn.WriteMessage(websocket.TextMessage, msg)
}
}
ReadPump: รับข้อความจาก client แล้วส่งต่อให้ room broadcastWritePump: รับข้อความจาก room แล้วส่งกลับไปยัง client
👥 การจัดการสมาชิกในห้อง
เพิ่มฟีเจอร์เช่นการแสดงรายชื่อผู้ใช้ในห้อง (List Members):
func (r *Room) ListMembers() []string {
members := []string{}
for id := range r.Clients {
members = append(members, id)
}
return members
}
และสามารถสร้าง API endpoint เช่น /join-room, /leave-room, /members เพื่อควบคุมผ่าน frontend ได้
🧠 แนวทางการนำไปใช้ใน Production
- ✅ ใช้ Redis Pub/Sub เพื่อแชร์ข้อความระหว่างหลาย instance
- ✅ ตั้งค่าจำกัดจำนวนผู้ใช้ต่อห้อง (Connection Limit per Room)
- ✅ เปิดใช้งาน Gzip Compression เพื่อลดขนาด Payload
🚀 ท้าให้ลอง!
- ลองสร้างระบบ Multi-room Chat ของคุณเอง
- เพิ่มฟีเจอร์เพิ่มเติม เช่น:
- ห้องแบบ Private
- Room Admin
- การแจ้งเตือนเมื่อมีผู้เข้าร่วมหรือออก
🔜 EP ถัดไป
EP.89: การทดสอบประสิทธิภาพ WebSocket Server ด้วยเครื่องมือ Load Testing
มาดูกันว่าระบบ WebSocket ของคุณสามารถรับโหลดระดับสูงได้แค่ไหน และเรียนรู้การใช้เครื่องมือสำหรับ Benchmark ระบบแบบมือโปร!
อ่านบทความ Series อื่นๆ
🔵 Facebook: https://www.facebook.com/superdev.academy.th
🔴 YouTube : Superdev Academy
📸 Instagram: Superdev Academy
🎬 TikTok: https://www.tiktok.com/@superdevacademy?lang=th-TH
🌐 Website: https://www.superdevacademy.com/