File size: 4,173 Bytes
6980b1d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupWebSocket = setupWebSocket;
const ws_1 = require("ws");
const url_1 = require("url");
function setupWebSocket(wss) {
    const clients = new Map();
    wss.on('connection', (ws, req) => {
        // Parse query parameters
        const query = (0, url_1.parse)(req.url || '', true).query;
        const tenantId = query.tenantId;
        const sessionToken = query.sessionToken;
        if (!tenantId || !sessionToken) {
            ws.close(1008, 'Missing tenantId or sessionToken');
            return;
        }
        // Set up connection
        ws.tenantId = tenantId;
        ws.sessionToken = sessionToken;
        ws.isAlive = true;
        // Store client connection
        const clientKey = `${tenantId}:${sessionToken}`;
        clients.set(clientKey, ws);
        console.log(`WebSocket client connected: ${clientKey}`);
        // Handle ping/pong for connection health
        ws.on('pong', () => {
            ws.isAlive = true;
        });
        ws.on('message', (data) => {
            try {
                const message = JSON.parse(data.toString());
                handleMessage(ws, message);
            }
            catch (error) {
                console.error('Invalid WebSocket message:', error);
                ws.send(JSON.stringify({ error: 'Invalid message format' }));
            }
        });
        ws.on('close', () => {
            console.log(`WebSocket client disconnected: ${clientKey}`);
            clients.delete(clientKey);
        });
        ws.on('error', (error) => {
            console.error('WebSocket error:', error);
            clients.delete(clientKey);
        });
        // Send welcome message
        ws.send(JSON.stringify({
            type: 'connection',
            message: 'Connected to chat server',
            timestamp: new Date().toISOString()
        }));
    });
    // Health check - ping clients every 30 seconds
    const interval = setInterval(() => {
        wss.clients.forEach((ws) => {
            if (ws.isAlive === false) {
                return ws.terminate();
            }
            ws.isAlive = false;
            ws.ping();
        });
    }, 30000);
    wss.on('close', () => {
        clearInterval(interval);
    });
    function handleMessage(ws, message) {
        switch (message.type) {
            case 'ping':
                ws.send(JSON.stringify({ type: 'pong', timestamp: new Date().toISOString() }));
                break;
            case 'typing':
                // Broadcast typing indicator to other participants (if multi-user chat)
                broadcastToSession(ws.tenantId, ws.sessionToken, {
                    type: 'typing',
                    sender: 'user',
                    timestamp: new Date().toISOString()
                }, ws);
                break;
            case 'stop_typing':
                broadcastToSession(ws.tenantId, ws.sessionToken, {
                    type: 'stop_typing',
                    sender: 'user',
                    timestamp: new Date().toISOString()
                }, ws);
                break;
            default:
                ws.send(JSON.stringify({ error: 'Unknown message type' }));
        }
    }
    function broadcastToSession(tenantId, sessionToken, message, sender) {
        const clientKey = `${tenantId}:${sessionToken}`;
        const client = clients.get(clientKey);
        if (client && client !== sender && client.readyState === ws_1.WebSocket.OPEN) {
            client.send(JSON.stringify(message));
        }
    }
    // Utility function to send message to specific session
    function sendToSession(tenantId, sessionToken, message) {
        const clientKey = `${tenantId}:${sessionToken}`;
        const client = clients.get(clientKey);
        if (client && client.readyState === ws_1.WebSocket.OPEN) {
            client.send(JSON.stringify(message));
            return true;
        }
        return false;
    }
    return {
        broadcastToSession,
        sendToSession,
        getConnectedClients: () => clients.size
    };
}
//# sourceMappingURL=websocket.js.map