สวัสดีครับ! วันนี้ผมจะมาสอนเทคนิคที่น่าสนใจมากสำหรับคนที่ต้องการทำระบบสนทนา AI แบบเรียลไทม์ด้วย WebSocket กันครับ โดยเฉพาะการจำลองการรับส่งข้อมูล (Traffic Mirroring) และการฉีดความผิดพลาด (Fault Injection) เพื่อทดสอบว่าระบบของเราแข็งแกร่งแค่ไหน

หลายคนอาจสงสัยว่าทำไมต้องทำแบบนี้ด้วย? คำตอบง่ายมากครับ เพราะในโลกจริง อินเทอร์เน็ตมีปัญหาได้เสมอ เช่น เน็ตหลุด ส่งข้อมูลช้า หรือเซิร์ฟเวอร์ล่ม ถ้าเราไม่ได้เตรียมระบบให้รับมือกับสิ่งเหล่านี้ล่วงหน้า ผู้ใช้งานจะเจอปัญหาหนักเลยครับ

WebSocket คืออะไร ทำไมถึงสำคัญสำหรับ AI สนทนา

WebSocket ก็คือช่องทางการสื่อสารระหว่างเว็บไซต์ของเรากับเซิร์ฟเวอร์ AI ที่เปิดไว้ตลอดเวลา ต่างจากการขอข้อมูลปกติที่ต้องส่งคำถามไปแล้วรอผลตอบกลับ แต่ WebSocket ช่วยให้ AI ตอบกลับมาได้ทีละน้อยทีละน้อยแบบต่อเนื่อง ทำให้ผู้ใช้เห็นคำตอบเกิดขึ้นทีละตัวอักษรเหมือน AI กำลังพิมพ์จริงๆ เลยครับ

สำหรับการใช้งานจริง ผมแนะนำให้ใช้ HolySheep AI เพราะมีความเร็วต่ำกว่า 50 มิลลิวินาที ราคาถูกกว่าที่อื่นถึง 85% มีระบบรองรับ WeChat และ Alipay สะดวกมากครับ

เตรียมพร้อมก่อนเริ่มต้น

สำหรับการเริ่มต้น คุณต้องมีสิ่งต่อไปนี้

เมื่อติดตั้งเสร็จแล้ว ให้เปิดโปรแกรม Terminal หรือ Command Prompt ขึ้นมา แล้วพิมพ์คำสั่งตรวจสอบว่าติดตั้งถูกต้องหรือเปล่า

node --version
npm --version

ถ้าเห็นเลขเวอร์ชันแสดงขึ้นมา แสดงว่าพร้อมแล้วครับ

สร้างโปรเจกต์แรกสำหรับ WebSocket AI

ให้เราสร้างโฟลเดอร์ใหม่สำหรับโปรเจกต์นี้กันครับ วิธีทำมีดังนี้

  1. เปิดโปรแกรม Terminal แล้วไปยังโฟลเดอร์ที่ต้องการเก็บโปรเจกต์
  2. พิมพ์คำสั่ง mkdir websocket-ai-test แล้วกด Enter
  3. พิมพ์ cd websocket-ai-test เพื่อเข้าไปในโฟลเดอร์
  4. พิมพ์ npm init -y เพื่อสร้างไฟล์ตั้งค่าโปรเจกต์

ต่อไปให้ติดตั้งไลบรารีที่จำเป็นสำหรับการทำ WebSocket ครับ

npm install ws dotenv ws-events

ไลบรารี ws จะช่วยให้เราสร้าง WebSocket Client และ Server ได้ง่ายมาก ส่วน dotenv จะช่วยจัดการตัวแปรสิ่งแวดล้อมอย่าง API Key อย่างปลอดภัยครับ

เขียนโค้ดเชื่อมต่อ WebSocket กับ HolySheep AI

ให้สร้างไฟล์ใหม่ชื่อ .env แล้วใส่ API Key ของคุณลงไปครับ

HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY

หมายเหตุสำคัญ: อย่าเผยแพร่ไฟล์ .env นี้ไปที่ GitHub หรือที่ไหนเลยนะครับ เพราะจะทำให้คนอื่นขโมย API Key ของเราได้! ควรสร้างไฟล์ .gitignore แล้วใส่ .env ลงไปด้วยครับ

ต่อไปสร้างไฟล์ websocket-client.js สำหรับเชื่อมต่อกับ AI ครับ

const WebSocket = require('ws');
require('dotenv').config();

// ตั้งค่าการเชื่อมต่อ WebSocket กับ HolySheep AI
const API_KEY = process.env.HOLYSHEEP_API_KEY;
const WS_URL = 'wss://api.holysheep.ai/v1/chat/completions';

function connectToAI() {
    console.log('กำลังเชื่อมต่อกับ HolySheep AI...');
    
    const ws = new WebSocket(WS_URL, {
        headers: {
            'Authorization': Bearer ${API_KEY},
            'Content-Type': 'application/json'
        }
    });

    ws.on('open', () => {
        console.log('✅ เชื่อมต่อสำเร็จแล้ว!');
        
        // ส่งข้อความไปถาม AI
        const message = {
            model: 'gpt-4.1',
            messages: [
                { role: 'user', content: 'สวัสดีครับ AI' }
            ],
            stream: true
        };
        
        ws.send(JSON.stringify(message));
        console.log('📤 ส่งข้อความแล้ว รอการตอบกลับ...');
    });

    ws.on('message', (data) => {
        const text = data.toString();
        
        // ข้อมูลที่ AI ส่งมาจะมาเป็น chunk ทีละส่วน
        if (text.startsWith('data: ')) {
            if (text.includes('[DONE]')) {
                console.log('\n✅ AI ตอบเสร็จแล้ว!');
                ws.close();
            } else {
                // ตัดคำว่า "data: " ออกแล้วแปลง JSON
                const json = JSON.parse(text.slice(6));
                const content = json.choices?.[0]?.delta?.content || '';
                if (content) {
                    process.stdout.write(content);
                }
            }
        }
    });

    ws.on('error', (error) => {
        console.error('❌ เกิดข้อผิดพลาด:', error.message);
    });

    ws.on('close', () => {
        console.log('\n🔌 การเชื่อมต่อถูกตัดแล้ว');
    });
}

connectToAI();

หลังจากนั้นให้รันโค้ดด้วยคำสั่ง

node websocket-client.js

ถ้าทุกอย่างถูกต้อง คุณจะเห็น AI ตอบกลับมาเป็นตัวอักษรทีละตัวครับ!

ทำ Traffic Mirroring เพื่อจำลองการรับส่งข้อมูล

Traffic Mirroring คือการทำสำเนาของการรับส่งข้อมูลจริง เพื่อนำไปวิเคราะห์หรือทดสอบโดยไม่กระทบระบบจริงครับ วิธีนี้เหมาะมากเมื่อต้องการเช็คว่าระบบจะทำงานอย่างไรกับข้อมูลจริง

ให้สร้างไฟล์ traffic-mirror.js สำหรับจำลองการรับส่งข้อมูลครับ

const WebSocket = require('ws');

// ข้อมูลตัวอย่างที่จำลอง - แทนที่ด้วยข้อมูลจริงได้
const sampleTraffic = [
    { type: 'user', content: 'สวัสดีครับ', timestamp: Date.now() },
    { type: 'user', content: 'พรุ่งนี้อากาศเป็นอย่างไร', timestamp: Date.now() + 1000 },
    { type: 'user', content: 'แนะนำร้านอาหารใกล้สยามหน่อย', timestamp: Date.now() + 5000 }
];

class TrafficMirror {
    constructor(port = 8080) {
        this.port = port;
        this.clients = new Set();
        this.trafficLog = [];
        this.startServer();
    }

    startServer() {
        const wss = new WebSocket.Server({ port: this.port });
        
        console.log(🔄 Traffic Mirror Server ทำงานที่ port ${this.port});
        
        wss.on('connection', (ws) => {
            console.log('📡 Client ใหม่เชื่อมต่อแล้ว');
            this.clients.add(ws);

            // ส่ง traffic ที่บันทึกไว้ให้ client ใหม่
            ws.send(JSON.stringify({
                type: 'history',
                data: this.trafficLog
            }));

            ws.on('message', (message) => {
                const data = JSON.parse(message);
                console.log('📥 ได้รับข้อมูล:', data);
                
                // บันทึกข้อมูลและส่งให้ทุก client
                this.recordTraffic(data);
                this.broadcast(data);
            });

            ws.on('close', () => {
                this.clients.delete(ws);
                console.log('📴 Client ตัดการเชื่อมต่อแล้ว');
            });
        });
    }

    recordTraffic(data) {
        this.trafficLog.push({
            ...data,
            recordedAt: new Date().toISOString()
        });
        console.log(📊 บันทึก traffic แล้ว มีทั้งหมด ${this.trafficLog.length} รายการ);
    }

    broadcast(data) {
        const message = JSON.stringify(data);
        this.clients.forEach(client => {
            if (client.readyState === WebSocket.OPEN) {
                client.send(message);
            }
        });
    }

    // ฟังก์ชันจำลอง traffic
    replayTraffic() {
        console.log('🔁 เริ่มจำลองการรับส่งข้อมูล...');
        
        sampleTraffic.forEach((traffic, index) => {
            setTimeout(() => {
                console.log(⏱️ ส่ง traffic ที่ ${index + 1}:, traffic);
                this.recordTraffic(traffic);
                this.broadcast(traffic);
            }, index * 2000);
        });
    }
}

// รัน server และจำลอง traffic
const mirror = new TrafficMirror(8080);

// จำลอง traffic หลังจาก server ทำงาน 2 วินาที
setTimeout(() => {
    mirror.replayTraffic();
}, 2000);

รันโค้ดด้วยคำสั่ง

node traffic-mirror.js

คุณจะเห็น Server รันขึ้นมา แล้วจำลองการรับส่งข้อมูล 3 รายการโดยอัตโนมัติครับ แต่ละรายการจะห่างกัน 2 วินาที พร้อมบันทึกลงใน log ด้วย

ทำ Fault Injection เพื่อทดสอบความทนทานของระบบ

Fault Injection คือการฉีดความผิดพลาดเข้าไปในระบบโดยตั้งใจ เพื่อดูว่าระบบจะรับมืออย่างไร ตัวอย่างความผิดพลาดที่พบบ่อยในโลกจริง เช่น

ให้สร้างไฟล์ fault-injection.js สำหรับทดสอบความทนทานครับ

const WebSocket = require('ws');

class FaultInjector {
    constructor(targetUrl, options = {}) {
        this.targetUrl = targetUrl;
        this.failRate = options.failRate || 0.3; // 30% ของ requests จะ fail
        this.latency = options.latency || 0; // delay มิลลิวินาที
        this.isActive = true;
    }

    // ตั้งค่าความน่าจะเป็นที่จะ fail
    setFailRate(rate) {
        this.failRate = rate;
        console.log(⚙️ ตั้ง fail rate ใหม่: ${rate * 100}%);
    }

    // ตั้งค่า latency ปลอม
    setLatency(ms) {
        this.latency = ms;
        console.log(⚙️ ตั้ง latency ใหม่: ${ms}ms);
    }

    // เปิด/ปิด fault injection
    toggle() {
        this.isActive = !this.isActive;
        console.log(🔧 Fault Injection: ${this.isActive ? 'เปิด' : 'ปิด'});
    }

    // สุ่มว่าจะ fail หรือไม่
    shouldFail() {
        return Math.random() < this.failRate;
    }

    // สร้าง WebSocket connection ที่มี fault injection
    connect(headers = {}) {
        const self = this;
        
        return new Promise((resolve, reject) => {
            // ถ้า fault injection ปิดอยู่ ให้เชื่อมต่อปกติ
            if (!this.isActive) {
                const ws = new WebSocket(this.targetUrl, { headers });
                resolve(ws);
                return;
            }

            // จำลอง latency
            if (this.latency > 0) {
                console.log(⏱️ จำลอง delay: ${this.latency}ms);
                setTimeout(() => {
                    if (this.shouldFail()) {
                        reject(new Error('❌ เชื่อมต่อไม่สำเร็จ (Fault Injection)'));
                    } else {
                        const ws = new WebSocket(self.targetUrl, { headers });
                        resolve(ws);
                    }
                }, this.latency);
            } else {
                if (this.shouldFail()) {
                    reject(new Error('❌ เชื่อมต่อไม่สำเร็จ (Fault Injection)'));
                } else {
                    const ws = new WebSocket(this.targetUrl, { headers });
                    resolve(ws);
                }
            }
        });
    }

    // ฟังก์ชันทดสอบหลายๆ รอบ
    async stressTest(iteration = 10) {
        console.log(\n🚀 เริ่มทดสอบความทนทาน: ${iteration} รอบ);
        console.log(   Fail Rate: ${this.failRate * 100}%);
        console.log(   Latency: ${this.latency}ms\n);

        let success = 0;
        let failed = 0;

        for (let i = 1; i <= iteration; i++) {
            process.stdout.write(รอบที่ ${i}/${iteration}: );
            
            try {
                await this.connect();
                console.log('✅ สำเร็จ');
                success++;
            } catch (error) {
                console.log(error.message);
                failed++;
            }

            // รอสักครู่ระหว่างรอบ
            await new Promise(r => setTimeout(r, 500));
        }

        console.log(\n📊 ผลทดสอบ:);
        console.log(   สำเร็จ: ${success} ครั้ง (${(success/iteration*100).toFixed(1)}%));
        console.log(   ล้มเหลว: ${failed} ครั้ง (${(failed/iteration*100).toFixed(1)}%));
    }
}

// ตัวอย่างการใช้งาน
const injector = new FaultInjector('wss://api.holysheep.ai/v1/chat/completions', {
    failRate: 0.2, // 20% จะ fail
    latency: 100   // เพิ่ม delay 100ms
});

// ตั้งค่า fail rate สูงขึ้นเพื่อดูว่าระบบรับมือได้ไหม
injector.setFailRate(0.4); // 40% จะ fail

// รัน stress test
injector.stressTest(10);

รันโค้ดด้วยคำสั่ง

node fault-injection.js

จะเห็นผลการทดสอบว่าใน 10 รอบ มีกี่รอบที่เชื่อมต่อสำเร็จและกี่รอบที่ fail ครับ ลองปรับค่าต่างๆ ดูนะครับ เช่น เปลี่ยน failRate เป็น 0.8 (80%) หรือเพิ่ม latency เป็น 500ms

รวมระบบทั้งหมดเข้าด้วยกัน

ให้สร้างไฟล์ full-system.js ที่รวมทุกอย่างเข้าด้วยกัน ทั้ง WebSocket Client, Traffic Mirror และ Fault Injection ครับ

const WebSocket = require('ws');
require('dotenv').config();

class AIChatSystem {
    constructor() {
        this.apiKey = process.env.HOLYSHEEP_API_KEY;
        this.wsUrl = 'wss://api.holysheep.ai/v1/chat/completions';
        this.conversationHistory = [];
        this.faultInjector = {
            enabled: false,
            failRate: 0.3,
            latency: 0
        };
    }

    enableFaultInjection(failRate = 0.3, latency = 0) {
        this.faultInjector = { enabled: true, failRate, latency };
        console.log(🔧 Fault Injection เปิดแล้ว: fail=${failRate*100}%, latency=${latency}ms);
    }

    disableFaultInjection() {
        this.faultInjector.enabled = false;
        console.log('🔧 Fault Injection ปิดแล้ว');
    }

    async sendMessage(userMessage) {
        // บันทึกข้อความผู้ใช้
        this.conversationHistory.push({
            role: 'user',
            content: userMessage,
            timestamp: Date.now()
        });

        console.log(\n👤 คุณ: ${userMessage});

        // ถ้าเปิด fault injection และโดนสุ่มให้ fail
        if (this.faultInjector.enabled && Math.random() < this.faultInjector.failRate) {
            console.log('❌ จำลองความผิดพลาด: เชื่อมต่อไม่สำเร็จ');
            return {
                success: false,
                error: 'Connection failed (simulated)'
            };
        }

        // จำลอง latency
        if (this.faultInjector.enabled && this.faultInjector.latency > 0) {
            await new Promise(r => setTimeout(r, this.faultInjector.latency));
        }

        // เชื่อมต่อกับ HolySheep AI
        return new Promise((resolve) => {
            const ws = new WebSocket(this.wsUrl, {
                headers: {
                    'Authorization': Bearer ${this.apiKey},
                    'Content-Type': 'application/json'
                }
            });

            let fullResponse = '';

            ws.on('open', () => {
                const request = {
                    model: 'gpt-4.1',
                    messages: this.conversationHistory,
                    stream: true
                };
                ws.send(JSON.stringify(request));
            });

            ws.on('message', (data) => {
                const text = data.toString();
                
                if (text.startsWith('data: ')) {
                    if (text.includes('[DONE]')) {
                        ws.close();
                    } else {
                        try {
                            const json = JSON.parse(text.slice(6));
                            const content = json.choices?.[0]?.delta?.content || '';
                            fullResponse += content;
                        } catch (e) {
                            // ข้าม chunk ที่ parse ไม่ได้
                        }
                    }
                }
            });

            ws.on('error', (error) => {
                console.log('❌ เกิดข้อผิดพลาด:', error.message);
                resolve({ success: false, error: error.message });
            });

            ws.on('close', () => {
                // บันทึกข้อความ AI
                if (fullResponse) {
                    this.conversationHistory.push({
                        role: 'assistant',
                        content: fullResponse,
                        timestamp: Date.now()
                    });
                    console.log(🤖 AI: ${fullResponse});
                }
                resolve({ success: true, response: fullResponse });
            });
        });
    }

    // จำลอง traffic ทั้งหมด
    exportTraffic() {
        return this.conversationHistory.map(msg => ({
            ...msg,
            type: msg.role === 'user' ? 'request' : 'response'
        }));
    }

    // รันทดสอบอัตโนมัติ
    async runTest() {
        console.log('🧪 เริ่มทดสอบระบบ AI Chat...\n');
        
        // เปิด fault injection
        this.enableFaultInjection(0.2, 50);
        
        const testMessages = [
            'สวัสดีครับ',
            'พรุ่งนี้อากาศเป็นอย่างไร',
            'แนะนำหนังสนุกๆ ดูไหม',
            'ขอบคุณครับ'
        ];

        for (const msg of testMessages) {
            await this.sendMessage(msg);
            await new Promise(r => setTimeout(r, 1000));
        }

        // ปิด fault injection แล้วทดสอบต่อ
        this.disableFaultInjection();
        console.log('\n🔄 ทดสอบต่อโดยไม่มี fault injection...');
        await this.sendMessage('ทดสอบระบบปกติ');
    }
}

// รันระบบ
const chat = new AIChatSystem();
chat.runTest();

ข้อผิดพลาดที่พบบ่อยและวิ�