การดู : 241

08/05/2026 06:52น.

EP.119 สร้างระบบ Real-time Document Editing แบบ Google Docs ด้วย WebSocket และ Go

EP.119 สร้างระบบ Real-time Document Editing แบบ Google Docs ด้วย WebSocket และ Go

#WebSocket

#Go

#Real-time Document

#Google Docs

การแก้เอกสารพร้อมกันหลายคน (Collaborative Editing) คือหนึ่งใน use case ที่ท้าทายที่สุดของระบบ Real-time เพราะต้องรับมือกับหลายปัญหาในเวลาเดียวกัน เช่น:

  • ผู้ใช้หลายคนพิมพ์พร้อมกัน
  • ความขัดแย้งของข้อความ (conflict)
  • ความต้องการให้ทุกคนเห็นผลลัพธ์ "ตรงกัน 100%"
  • ประสบการณ์การใช้งานที่ลื่นไหล และ latency ต่ำมาก

 

บทความนี้จะพาคุณสร้างระบบ Real-time Document Editing โดยใช้ Go + WebSocket เป็นแกนหลัก พร้อมแนวคิด Conflict Resolution ที่ใช้จริงในระบบระดับโลก เช่น Google Docs หรือ Notion

 

🧠 ภาพรวม Architecture ของ Collaborative Editing

 

โครงสร้างระบบพื้นฐาน:

Client (Browser/App)
→ WebSocket
→ Collaboration Server (Go)
→ Broadcast Update
→ Client ทุกคนใน Document เดียวกัน

 

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

  • Document State – สถานะปัจจุบันของเอกสาร
  • Operations / Changes – การแก้ไขของผู้ใช้
  • Version / Sequence – ลำดับการเปลี่ยนแปลง
  • Conflict Resolution Engine – กลไกจัดการเมื่อเกิดข้อความชนกัน

 

✍️ 1. รูปแบบข้อมูลการแก้ไข (Edit Operation)

 

ระบบที่ดีจะไม่ส่ง "ทั้งเอกสาร" ทุกครั้ง แต่จะส่งเฉพาะ "สิ่งที่เปลี่ยน" เช่น:

{
  "doc_id": "doc-123",
  "user_id": "user-a",
  "op": "insert",
  "position": 15,
  "text": "Hello",
  "version": 42
}

 

Operation ที่ใช้บ่อย:

  • insert – แทรกข้อความ
  • delete – ลบข้อความ
  • replace – แทนที่ข้อความ

 

🔄 2. Real-time Sync ด้วย WebSocket

 

เมื่อผู้ใช้พิมพ์:

  1. Client สร้าง Operation
  2. ส่งผ่าน WebSocket
  3. Server ตรวจสอบ + apply
  4. Broadcast ไปยังทุกคนในเอกสารเดียวกัน

 

⚙️ 3. ตัวอย่าง WebSocket Server ด้วย Go

 

type EditOperation struct {
	DocID    string `json:"doc_id"`
	UserID   string `json:"user_id"`
	Op       string `json:"op"`
	Position int    `json:"position"`
	Text     string `json:"text"`
	Version  int    `json:"version"`
}

var documents = make(map[string]string)
var docVersion = make(map[string]int)

func handleEdit(conn *websocket.Conn) {
	for {
		var op EditOperation
		if err := conn.ReadJSON(&op); err != nil {
			return
		}

		current := documents[op.DocID]
		updated := applyOperation(current, op)

		documents[op.DocID] = updated
		docVersion[op.DocID]++

		broadcast(op.DocID, updated, docVersion[op.DocID])
	}
}

 

🧩 4. Conflict Resolution คืออะไร?

 

Conflict เกิดขึ้นเมื่อ:

  • ผู้ใช้ 2 คนแก้ไขตำแหน่งเดียวกัน
  • Operation มาถึง server ไม่พร้อมกัน

 

แนวทางการแก้:

  • OT (Operational Transformation) – ใช้ใน Google Docs
  • CRDT (Conflict-free Replicated Data Type) – ใช้ใน Notion, Figma
  • Version Checking & Rebase – สำหรับระบบเริ่มต้น

 

if op.Version != docVersion[op.DocID] {
	// rebase หรือ reject
	return
}

 

👥 5. การจัดการผู้ใช้หลายคนในเอกสารเดียวกัน

 

  • แยก Room ตาม doc_id
  • Broadcast เฉพาะผู้ใช้ใน document เดียวกัน
  • Track ตำแหน่ง cursor:

 

{
  "type": "cursor",
  "user": "user-b",
  "position": 22
}

 

⚡ 6. Performance Optimization

 

เทคนิคเพื่อให้ระบบทำงานลื่น:

  • ส่งเฉพาะ Operation ไม่ส่งทั้ง Document
  • ใช้ Debounce ป้องกัน flood
  • Batch operation ถี่ ๆ
  • ใช้ Binary Protocol (ในระบบใหญ่)

 

🔐 7. Security ที่ระบบควรมี

 

  • ตรวจสอบสิทธิ์ผู้ใช้ (Access Control)
  • ยืนยันตัวตน (Auth)
  • Rate Limiting
  • ป้องกัน spam / flood

 

🚀 ท้าให้ลอง!

 

ลองทำ Mini Project:

  • ให้ 2–3 คนแก้เอกสารพร้อมกัน
  • Sync ตัวอักษรแบบ Real-time
  • แสดง cursor ของคนอื่น
  • ใช้ version ในการป้องกัน conflict

 

หากคุณทำจุดนี้ได้ = คุณเข้าใจ Real-time System ในระดับ Production แล้ว! 🎯

 


 

🔮 ตอนถัดไป: EP.120 Whiteboard & Real-time Drawing

 

ครั้งหน้าเราจะขยับจาก “ตัวอักษร” ไปสู่ “การวาดรูป” ด้วยระบบ Real-time Drawing Sync สำหรับ Whiteboard App เหมือน Miro หรือ FigJam
พร้อมการ sync canvas, mouse position, shape, และ undo-redo แบบทันที! 🎨