การสื่อสารแบบ bidirectional ระหว่าง client และ server เป็นหัวใจสำคัญของแอปพลิเคชัน AI chat ยุคใหม่ ในบทความนี้ผมจะพาทุกท่านไปทำความรู้จักกับ WebSocket protocol วิธีการ implement การเชื่อมต่อแบบ real-time กับ HolySheep AI รวมถึงเทคนิค 断线重连 (reconnection)> ที่จะช่วยให้แอปพลิเคชันของท่านทำงานได้อย่างเสถียรแม้ในสภาพเครือข่ายที่ไม่เสถียร
WebSocket vs HTTP: ทำไมต้องเลือก WebSocket
จากประสบการณ์ในการพัฒนาแชทบอทหลายสิบโปรเจกต์ ผมพบว่า WebSocket มีความได้เปรียบเหนือ HTTP polling ในหลายด้าน:
- ความหน่วงต่ำ (Latency): ลดได้ถึง <50ms เมื่อเทียบกับ HTTP polling ที่ต้องส่ง request ใหม่ทุกครั้ง
- ประหยัดทรัพยากร: ไม่ต้องสร้าง TCP connection ใหม่ทุกครั้ง
- Server push: server สามารถส่งข้อมูลไปยัง client ได้โดยไม่ต้องรอ request
- Full-duplex: สื่อสารได้ทั้งสองทิศทางพร้อมกัน
การตั้งค่า WebSocket Client สำหรับ HolySheep AI
ก่อนเริ่มต้น ท่านต้องมี API key จาก สมัครที่นี่ โดย HolySheep AI มีอัตราแลกเปลี่ยนที่คุ้มค่ามาก คือ ¥1 = $1 ซึ่งประหยัดกว่า API ทั่วไปถึง 85%+ รองรับการชำระเงินผ่าน WeChat/Alipay และมี เครดิตฟรีเมื่อลงทะเบียน
1. WebSocket Connection แบบ Stream Response
ด้านล่างนี้คือโค้ดสำหรับการเชื่อมต่อ WebSocket เพื่อรับ stream response จาก AI model ผ่าน HolySheep API:
// WebSocket Client สำหรับ HolySheep AI Streaming Chat
// ความหน่วงเฉลี่ยที่วัดได้: <50ms
class HolySheepWebSocket {
constructor(apiKey) {
this.apiKey = apiKey;
this.ws = null;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectDelay = 1000;
this.messageQueue = [];
this.isConnected = false;
// base_url ต้องเป็น https://api.holysheep.ai/v1 เท่านั้น
this.baseUrl = 'wss://api.holysheep.ai/v1/chat/completions';
}
connect() {
return new Promise((resolve, reject) => {
try {
// สร้าง WebSocket connection
this.ws = new WebSocket(this.baseUrl, {
headers: {
'Authorization': Bearer ${this.apiKey},
'Content-Type': 'application/json'
}
});
this.ws.on('open', () => {
console.log('✅ WebSocket เชื่อมต่อสำเร็จ');
console.log(📊 ความหน่วง: ${Date.now() - this.connectStartTime}ms);
this.isConnected = true;
this.reconnectAttempts = 0;
this.flushMessageQueue();
resolve();
});
this.ws.on('message', (event) => {
this.handleMessage(event);
});
this.ws.on('error', (error) => {
console.error('❌ WebSocket Error:', error);
reject(error);
});
this.ws.on('close', (event) => {
console.log('🔌 Connection closed:', event.code, event.reason);
this.isConnected = false;
this.handleDisconnect();
});
this.connectStartTime = Date.now();
} catch (error) {
reject(error);
}
});
}
sendMessage(content, model = 'gpt-4.1') {
const message = {
model: model,
messages: [
{ role: 'user', content: content }
],
stream: true
};
if (this.isConnected && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
} else {
this.messageQueue.push(message);
}
}
handleMessage(event) {
// ประมวลผล SSE stream data
const lines = event.data.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') {
console.log('✅ Stream เสร็จสมบูรณ์');
this.onComplete?.();
return;
}
try {
const parsed = JSON.parse(data);
const content = parsed.choices?.[0]?.delta?.content;
if (content) {
this.onChunk?.(content);
}
} catch (e) {
// ข้าม JSON parse error
}
}
}
}
handleDisconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
console.log(🔄 กำลังพยายามเชื่อมต่อใหม่... (ครั้งที่ ${this.reconnectAttempts}/${this.maxReconnectAttempts}));
console.log(⏱️ รอ ${delay}ms);
setTimeout(() => {
this.connect().catch(() => {});
}, delay);
} else {
console.error('❌ เชื่อมต่อใหม่ไม่สำเร็จ กรุณาตรวจสอบ API key หรือสถานะเครือข่าย');
}
}
flushMessageQueue() {
while (this.messageQueue.length > 0 && this.isConnected) {
const message = this.messageQueue.shift();
this.ws.send(JSON.stringify(message));
}
}
close() {
if (this.ws) {
this.ws.close(1000, 'Client initiated close');
}
}
}
// วิธีใช้งาน
const client = new HolySheepWebSocket('YOUR_HOLYSHEEP_API_KEY');
client.onChunk = (chunk) => {
process.stdout.write(chunk); // แสดงผล streaming แบบ real-time
};
client.onComplete = () => {
console.log('\n✅ การสนทนาเสร็จสมบูรณ์');
};
client.connect()
.then(() => client.sendMessage('สวัสดี คุณเป็นอย่างไรบ้าง?'))
.catch(err => console.error('เชื่อมต่อไม่สำเร็จ:', err));
2. การ Implement Reconnection Logic แบบอัตโนมัติ
หนึ่งในความท้าทายที่ใหญ่ที่สุดของ WebSocket คือการจัดการกับการหลุด connection โค้ดด้านล่างนี้แสดงการ implement 断线重连 หรือ automatic reconnection ที่ทำงานได้อย่างเสถียร:
// Advanced WebSocket Manager พร้อม Exponential Backoff Reconnection
// รองรับ: heartbeat, auto-reconnect, message buffering
class WebSocketManager {
constructor(options = {}) {
this.url = options.url || 'wss://api.holysheep.ai/v1/chat/completions';
this.apiKey = options.apiKey;
this.heartbeatInterval = options.heartbeatInterval || 30000;
this.maxReconnectDelay = options.maxReconnectDelay || 30000;
this.baseReconnectDelay = options.baseReconnectDelay || 1000;
this.ws = null;
this.reconnectAttempts = 0;
this.isManualClose = false;
this.messageBuffer = [];
this.listeners = new Map();
this.heartbeatTimer = null;
this.reconnectTimer = null;
}
// Event emitter methods
on(event, callback) {
if (!this.listeners.has(event)) {
this.listeners.set(event, []);
}
this.listeners.get(event).push(callback);
}
emit(event, data) {
const callbacks = this.listeners.get(event) || [];
callbacks.forEach(cb => cb(data));
}
async connect() {
return new Promise((resolve, reject) => {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
resolve();
return;
}
try {
this.ws = new WebSocket(this.url);
this.ws.binaryType = 'arraybuffer';
// กำหนด headers
this.ws.onopen = () => {
console.log(🟢 [${new Date().toISOString()}] WebSocket Connected);
console.log(📡 เชื่อมต่อผ่าน HolySheep API - Latency: ${Date.now() - this.connectTime}ms);
this.reconnectAttempts = 0;
this.startHeartbeat();
this.flushBuffer();
this.emit('connected', {});
resolve();
};
this.ws.onmessage = (event) => {
this.handleMessage(event);
};
this.ws.onerror = (error) => {
console.error('🔴 WebSocket Error:', error);
this.emit('error', error);
reject(error);
};
this.ws.onclose = (event) => {
console.log(🔴 [${new Date().toISOString()}] Connection closed: ${event.code});
this.stopHeartbeat();
this.emit('disconnected', { code: event.code, reason: event.reason });
if (!this.isManualClose) {
this.scheduleReconnect();
}
};
this.connectTime = Date.now();
} catch (error) {
reject(error);
}
});
}
handleMessage(event) {
// รองรับทั้ง text และ binary data
let data;
if (event.data instanceof ArrayBuffer) {
data = new TextDecoder().decode(event.data);
} else {
data = event.data;
}
// Parse SSE format
const lines = data.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const jsonStr = line.slice(6);
if (jsonStr === '[DONE]') {
this.emit('streamEnd', {});
continue;
}
try {
const parsed = JSON.parse(jsonStr);
this.emit('message', parsed);
// ส่งต่อ content chunk สำหรับ streaming
const content = parsed.choices?.[0]?.delta?.content;
if (content) {
this.emit('streamChunk', { content, full: parsed });
}
} catch (e) {
// Skip invalid JSON
}
}
}
}
send(data) {
const message = JSON.stringify(data);
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(message);
} else {
// Buffer message รอเชื่อมต่อใหม่
this.messageBuffer.push(message);
console.log('📦 Message buffered, รอ reconnect...');
}
}
flushBuffer() {
while (this.messageBuffer.length > 0) {
const msg = this.messageBuffer.shift();
this.ws.send(msg);
}
}
startHeartbeat() {
this.heartbeatTimer = setInterval(() => {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
// Send ping
this.ws.send(JSON.stringify({ type: 'ping' }));
console.log('💓 Heartbeat sent');
}
}, this.heartbeatInterval);
}
stopHeartbeat() {
if (this.heartbeatTimer) {
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}
}
scheduleReconnect() {
if (this.reconnectTimer) {
return;
}
// Exponential backoff
const delay = Math.min(
this.baseReconnectDelay * Math.pow(2, this.reconnectAttempts),
this.maxReconnectDelay
);
console.log(⏰ กำลัง reconnect ใน ${delay}ms (ครั้งที่ ${this.reconnectAttempts + 1}));
this.reconnectTimer = setTimeout(async () => {
this.reconnectTimer = null;
this.reconnectAttempts++;
try {
await this.connect();
console.log('✅ Reconnect สำเร็จ!');
} catch (error) {
console.error('❌ Reconnect ล้มเหลว:', error.message);
if (this.reconnectAttempts < 10) {
this.scheduleReconnect();
} else {
this.emit('reconnectFailed', {});
}
}
}, delay);
}
disconnect() {
this.isManualClose = true;
this.stopHeartbeat();
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
if (this.ws) {
this.ws.close(1000, 'Manual disconnect');
this.ws = null;
}
}
}
// ตัวอย่างการใช้งาน
async function demoStreamingChat() {
const wsManager = new WebSocketManager({
url: 'wss://api.holysheep.ai/v1/chat/completions',
apiKey: 'YOUR_HOLYSHEEP_API_KEY',
heartbeatInterval: 25000,
baseReconnectDelay: 1000,
maxReconnectDelay: 30000
});
let fullResponse = '';
wsManager.on('connected', () => {
console.log('🎉 เริ่มสนทนากับ AI...');
});
wsManager.on('streamChunk', ({ content }) => {
fullResponse += content;
process.stdout.write(content);
});
wsManager.on('streamEnd', () => {
console.log('\n\n📝 คำตอบเต็ม:', fullResponse);
});
wsManager.on('disconnected', ({ code, reason }) => {
console.log(🔌 หลุดการเชื่อมต่อ (code: ${code}));
});
wsManager.on('reconnectFailed', () => {
console.error('🚨 Reconnect ล้มเหลวหลายครั้ง กรุณาตรวจสอบเครือข่าย');
});
try {
await wsManager.connect();
wsManager.send({
model: 'gpt-4.1',
messages: [
{ role: 'system', content: 'คุณเป็นผู้ช่วย AI ที่เป็นมิตร' },
{ role: 'user', content: 'อธิบายเกี่ยวกับ WebSocket protocol สั้นๆ' }
],
stream: true