การดู : 231
22/04/2026 07:11น.

EP.42 การเพิ่มฟีเจอร์ Read Receipts (การแจ้งเตือนว่าอ่านแล้ว) ใน WebSocket Chat
#Chat UX
#Chat Features
#Message Read Status
#WebSocket API
#Real-Time Chat
#Golang
#Go
#WebSocket
#Read Receipts
ทำไมต้องมี Read Receipts ใน WebSocket Chat?
Read Receipts หรือการแจ้งเตือนว่าอ่านแล้ว เป็นฟีเจอร์สำคัญที่ช่วยให้ผู้ใช้สามารถทราบได้ว่า:
- ข้อความที่ส่งไปถึงปลายทางได้รับการอ่านแล้วหรือยัง
- ช่วยให้ผู้ส่งมั่นใจว่าข้อความไม่ได้ถูกมองข้าม
- สร้างประสบการณ์ที่ดีขึ้นในการสื่อสารแบบเรียลไทม์
ตัวอย่างแอปพลิเคชันที่ใช้ Read Receipts เช่น WhatsApp, Messenger, LINE ซึ่งจะแสดงเครื่องหมายถูกหรือไอคอนพิเศษเมื่อข้อความถูกอ่าน
โครงสร้างของระบบ Read Receipts ใน WebSocket Chat
- WebSocket Server - รับและส่งสถานะ "อ่านแล้ว" ให้กับผู้ใช้ในแชท
- Database - เก็บสถานะข้อความ (ยังไม่อ่าน/อ่านแล้ว)
- Frontend (Client-Side) - อัปเดต UI เมื่อข้อความถูกอ่าน
การเพิ่มฟีเจอร์ Read Receipts ใน WebSocket Server
1. อัปเกรด WebSocket Server ให้รองรับ Read Receipts
ไฟล์ websocket_server.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"sync"
"github.com/gorilla/websocket"
)
type ReadReceipt struct {
MessageID int `json:"messageID"`
Reader string `json:"reader"`
}
type Message struct {
ID int `json:"id"`
Content string `json:"content"`
Sender string `json:"sender"`
ReadBy []string `json:"readBy"`
}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
var (
clients = make(map[*websocket.Conn]bool)
messages = make(map[int]*Message)
broadcast = make(chan ReadReceipt)
mu sync.Mutex
)
func handleConnections(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil)
defer conn.Close()
clients[conn] = true
for {
var receipt ReadReceipt
err := conn.ReadJSON(&receipt)
if err != nil {
delete(clients, conn)
break
}
broadcast <- receipt
}
}
func handleMessages() {
for {
receipt := <-broadcast
mu.Lock()
if msg, exists := messages[receipt.MessageID]; exists {
msg.ReadBy = append(msg.ReadBy, receipt.Reader)
}
mu.Unlock()
for client := range clients {
err := client.WriteJSON(receipt)
if err != nil {
client.Close()
delete(clients, client)
}
}
}
}
func main() {
http.HandleFunc("/ws", handleConnections)
go handleMessages()
fmt.Println("WebSocket Server Running on Port 8080")
http.ListenAndServe(":8080", nil)
}2. การเพิ่ม Read Receipts ใน Frontend (Client-Side)
ไฟล์ client.js
const socket = new WebSocket("ws://localhost:8080/ws");
const messagesContainer = document.getElementById("messages");
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.messageID) {
document.getElementById(`msg-${data.messageID}`).innerText += " ✔ Read";
}
};
function sendReadReceipt(messageID) {
socket.send(JSON.stringify({ messageID, reader: "JohnDoe" }));
}
function displayMessage(id, content) {
const msgElement = document.createElement("p");
msgElement.id = `msg-${id}`;
msgElement.innerText = content;
msgElement.onclick = () => sendReadReceipt(id);
messagesContainer.appendChild(msgElement);
}การแสดง Read Receipts บน UI
ไฟล์ index.html
<div id="messages"></div>3. การทดสอบระบบ
- รัน WebSocket Server
go run websocket_server.go- เปิดหน้าเว็บหลายแท็บแล้วส่งข้อความ
- คลิกที่ข้อความเพื่อส่งสถานะ "อ่านแล้ว"
ท้าให้ลอง!
ลองเพิ่ม การแจ้งเตือนเฉพาะผู้ส่ง (Push Notification for Read Receipts) เพื่อแจ้งให้ผู้ส่งทราบทันทีเมื่อข้อความถูกอ่าน
EP ถัดไป
ใน EP.43, เราจะเพิ่ม ฟีเจอร์ปักหมุดข้อความ (Pinned Messages) ใน WebSocket Chat 🚀