การดู : 292

06/05/2026 08:38น.

EP.41 การเพิ่มฟีเจอร์แสดงสถานะการพิมพ์ (Typing Indicator) ใน WebSocket Chat

EP.41 การเพิ่มฟีเจอร์แสดงสถานะการพิมพ์ (Typing Indicator) ใน WebSocket Chat

#Chat UX

#Typing Status

#WebSocket API

#WebSocket Chat

#Real-Time Chat

#Golang

#Go

#WebSocket

#Typing Indicator

ทำไมต้องมี Typing Indicator ใน WebSocket Chat?

Typing Indicator ช่วยให้ผู้ใช้สามารถรับรู้ได้ว่า คู่สนทนากำลังพิมพ์อยู่ ทำให้การสื่อสารในแชทมีความลื่นไหลและตอบสนองต่อผู้ใช้งานได้ดีขึ้น เหมาะสำหรับ:

  • แอปพลิเคชันแชทส่วนตัวและกลุ่ม เช่น WhatsApp, Messenger
  • ระบบสนับสนุนลูกค้า (Customer Support Chat) ที่ตัวแทนสามารถแจ้งให้ลูกค้าทราบว่ากำลังตอบกลับ
  • แพลตฟอร์มชุมชนและโซเชียลมีเดีย ที่ต้องการให้ประสบการณ์ใช้งานสมจริงขึ้น

โครงสร้างของระบบ Typing Indicator ใน WebSocket Chat

  1. WebSocket Server - รับและกระจายสถานะการพิมพ์ไปยังผู้ใช้ที่อยู่ในห้องแชทเดียวกัน
  2. Frontend (Client-Side) - ส่งและรับสถานะการพิมพ์ พร้อมแสดงผลบน UI
  3. Database (Optional) - สามารถเก็บบันทึกการพิมพ์ได้หากต้องการวิเคราะห์พฤติกรรมผู้ใช้

การเพิ่มฟีเจอร์ Typing Indicator ใน WebSocket Server

1. อัปเกรด WebSocket Server ให้รองรับ Typing Indicator

ไฟล์ websocket_server.go

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "sync"

    "github.com/gorilla/websocket"
)

type TypingStatus struct {
    RoomID  int    `json:"roomID"`
    Sender  string `json:"sender"`
    Typing  bool   `json:"typing"`
}

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool { return true },
}

var (
    clients   = make(map[*websocket.Conn]bool)
    broadcast = make(chan TypingStatus)
    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 status TypingStatus
        err := conn.ReadJSON(&status)
        if err != nil {
            delete(clients, conn)
            break
        }
        broadcast <- status
    }
}

func handleMessages() {
    for {
        status := <-broadcast
        fmt.Printf("User %s is typing: %v\n", status.Sender, status.Typing)
        for client := range clients {
            err := client.WriteJSON(status)
            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. เพิ่มฟังก์ชัน Typing Indicator ใน Frontend (Client-Side)

ไฟล์ client.js

const socket = new WebSocket("ws://localhost:8080/ws");
const typingIndicator = document.getElementById("typing-indicator");
let typingTimeout;

socket.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.typing) {
        typingIndicator.innerText = `${data.sender} is typing...`;
    } else {
        typingIndicator.innerText = "";
    }
};

function sendTypingStatus(isTyping) {
    socket.send(JSON.stringify({ roomID: 1, sender: "JohnDoe", typing: isTyping }));
}

document.getElementById("message-input").addEventListener("input", () => {
    sendTypingStatus(true);
    clearTimeout(typingTimeout);
    typingTimeout = setTimeout(() => sendTypingStatus(false), 3000);
});

การแสดง Typing Indicator บน UI

ไฟล์ index.html

<input type="text" id="message-input" placeholder="Type a message...">
<p id="typing-indicator"></p>

3. การทดสอบระบบ

  1. รัน WebSocket Server
go run websocket_server.go
  1. เปิดหน้าเว็บหลายแท็บแล้วพิมพ์ข้อความ
  2. ดูผลลัพธ์ที่ WebSocket Server และ UI

ท้าให้ลอง!

ลองเพิ่ม ระบบแจ้งเตือนเมื่อผู้ใช้หยุดพิมพ์ (Stop Typing Indicator) โดยปรับปรุงโค้ดให้ตรวจจับเมื่อไม่มีการพิมพ์หลังจากระยะเวลาหนึ่ง


EP ถัดไป

ใน EP.42, เราจะเพิ่ม ฟีเจอร์ Read Receipts (การแจ้งเตือนว่าอ่านแล้ว) ใน WebSocket Chat 🚀