การเชื่อมต่อซ้ำหลังหลุด (Reconnection Strategy)
ในโลกความเป็นจริง เครือข่ายไม่ได้เสถียรเสมอไป ผู้ใช้งานอาจจะเดินเข้าลิฟต์ เปลี่ยนเสาสัญญาณ หรือปิดจอสมาร์ทโฟน ซึ่งล้วนทำให้การเชื่อมต่อ WebSocket ดับวูบ (Disconnect)
นี่คือคำแนะนำแนวทางการเขียนหน้าบ้าน (Frontend Client) เพื่อรับมือปัญหาหลุดบ่อย (Flaky Network) ได้อย่างไร้รอยต่อ
1. การดักจับเหตุการณ์การหลุด
สัญญาณการหลุดจะเกิดขึ้นใน Event Listener ws.onclose หรือ ws.onerror ของ WebSocket Object เสมอ
ws.onclose = (event) => {
// โค้ดที่ RawPush แจ้งสถานะการปิดจะอยู่ที่ event.code
console.log("Disconnected! Code:", event.code);
console.log("Reason:", event.reason);
// ดูว่าเป็นความตั้งใจหลุดหรือไม่
if (!event.wasClean) {
console.log("เน็ตหลุดกะทันหัน! ควรพยายามต่อใหม่");
}
};ตัวอย่างรหัสบอกสาเหตุ (Close Codes)
1000: ปิดด้วยดี (คุณสั่งปิดแบบ Normal Closure ย้ายหน้าเว็บ)1006: ปิดโดยผิดปกติกะทันหัน (เน็ตหลุด / สัญญาณตาย) <-- อาการนี้ควรช่วยต่อใหม่!4001: Server สั่ง close (Token ผิด / Auth Timeout) <-- อาการนี้ ไม่ควร ต่อใหม่จนกว่าจะขอ Token ใหม่จาก Backend
2. วิธีการทำ Exponential Backoff
นักพัฒนา ไม่ควรสั่ง connect() ถี่ๆ รัวๆ ทันทีที่เน็ตหลุด เพราะจะเสี่ยงทำให้ฝั่ง Client หน้าเว็บแฮงค์ค้าง และทำให้ Server กลายเป็นโดนยิงถล่ม (DDoS)
แนวปฎิบัติมาตรฐาน: การเวียนตั้งเวลาให้พยายามค่อยๆ ต่อใหม่ (Retry) ทิ้งช่วงห่างขึ้นเรื่อยๆ เรียกว่า Exponential Backoff (2วิ... 4วิ... 8วิ... หลุด)
นี่คือโค้ดตัวอย่างเพื่อให้เชื่อมต่อ RawPush อัตโนมัติ:
let ws;
const publicKey = "pk_yourproject...";
let authData = null; // เก็บค่า { token, signature } จาก Backend
let reconnectAttempts = 0;
const maxAttempts = 10;
function connect() {
ws = new WebSocket(`wss://api.rawpush.com/ws?app_key=${publicKey}`);
ws.onopen = () => {
// ล้างตัวนับใหม่เมื่อต่อสำเร็จ
reconnectAttempts = 0;
// Auth อีกครั้งหลังหลุด
ws.send(JSON.stringify({
cmd: "auth",
token: authData.token,
signature: authData.signature
}));
};
ws.onmessage = (event) => {
//... รับข้อมูล
};
ws.onclose = (e) => {
// ถ้าโดน block หรือ Token ผิด (Code 4xxx) ไม่ต้องพยายามต่อใหม่
if (e.code >= 4000) return;
if (reconnectAttempts < maxAttempts) {
// หน่วงเวลาช้าลง 2 เท่า ทุกครั้ง (เริ่มต้นที่ 1000 มิลลิวินาที)
const timeout = Math.pow(2, reconnectAttempts) * 1000;
reconnectAttempts++;
console.log(`พยายามเชื่อมต่อใหม่รอบที่ ${reconnectAttempts} ในอีก ${timeout/1000} วินาที...`);
setTimeout(() => connect(), timeout);
} else {
console.error("เชื่อมต่อใหม่ไม่สำเร็จ (ยอมแพ้)");
}
};
}
// เรียกให้ทำงานครั้งแรก
connect();3. สิ่งที่ควรทำหลังการเชื่อมต่อซ้ำ
เคล็ดลับสำคัญ! ระบบของ RawPush เป็นแบบส่ง-รับ ณ วินาทีนั้น ๆ หากเน็ตของคุณหลุดไป 5 นาที... พอพยายามต่อกลับมาติดใหม่ แล้วรันบรรทัดคำสั่ง auth กับ subscribe กลับคืนเข้ามา ข้อความที่ส่งช่วงที่คุณเน็ตหลุดไป 5 วินาทีนั้นสูญหายถาวร (Fire and Forget) จะไม่ได้ถูกส่งย้อนหลังกลับมาให้
หากแอปพลิเคชันของคุณคือ "ระบบ Real-time สำคัญ" (เช่น จอเทรดหุ้น แดชบอร์ดมอนิเตอร์สถานะ หรือแชท) สิ่งที่ Client (ฝั่ง Frontend) ต้องทำหลังจาก onopen ต่อติดใหม่คือ:
- รีบเรียก REST API ดึงข้อมูลย้อนหลัง (Database) เพื่อเช็คว่ามี data อะไรมาใหม่บ้างตอนที่เน็ตหลุด (Fetch History API ของ Backend คุณเอง)
- วาดข้อมูลอดีตลงหน้าจอ
- พอวาดเสร็จ ก็เริ่มรับ Event จาก RawPush WebSocket ตามปกติ
แค่นี้ก็จะได้ประสบการณ์ Real-time แบบข้ามช่วงเน็ตหลุดได้อย่างไร้รอยต่อแล้ว!
