| | |
| | |
| | |
| | |
| |
|
| | import config from '../../config.js'; |
| | import { generateId } from '../utils/idGenerator.js'; |
| |
|
| | const clients = new Map(); |
| |
|
| | export const setupWebSocket = (wss) => { |
| | wss.on('connection', (ws) => { |
| | const clientId = generateId(); |
| | let clientSessionId = null; |
| | |
| | ws.clientId = clientId; |
| | ws.isAlive = true; |
| | |
| | ws.on('pong', () => { |
| | ws.isAlive = true; |
| | }); |
| | |
| | ws.on('message', (data) => { |
| | try { |
| | const message = JSON.parse(data.toString()); |
| | |
| | if (message.type === 'register' && message.sessionId) { |
| | clientSessionId = message.sessionId; |
| | |
| | if (clients.has(clientSessionId)) { |
| | const oldClient = clients.get(clientSessionId); |
| | if (oldClient && oldClient.readyState === 1) { |
| | oldClient.close(); |
| | } |
| | } |
| | |
| | clients.set(clientSessionId, ws); |
| | ws.sessionId = clientSessionId; |
| | |
| | ws.send(JSON.stringify({ |
| | type: 'registered', |
| | sessionId: clientSessionId |
| | })); |
| | } |
| | |
| | handleWebSocketMessage(ws, message); |
| | } catch (error) {} |
| | }); |
| | |
| | ws.on('close', () => { |
| | if (clientSessionId) { |
| | clients.delete(clientSessionId); |
| | } |
| | }); |
| | |
| | ws.on('error', () => { |
| | if (clientSessionId) { |
| | clients.delete(clientSessionId); |
| | } |
| | }); |
| | |
| | ws.send(JSON.stringify({ |
| | type: 'connected', |
| | clientId |
| | })); |
| | }); |
| | |
| | const interval = setInterval(() => { |
| | wss.clients.forEach((ws) => { |
| | if (ws.isAlive === false) { |
| | return ws.terminate(); |
| | } |
| | ws.isAlive = false; |
| | ws.ping(); |
| | }); |
| | }, config.websocket.heartbeat); |
| | |
| | wss.on('close', () => { |
| | clearInterval(interval); |
| | }); |
| | }; |
| |
|
| | const handleWebSocketMessage = (ws, message) => { |
| | if (message.type === 'ping') { |
| | ws.send(JSON.stringify({ type: 'pong' })); |
| | } |
| | }; |
| |
|
| | export const sendToSession = (sessionId, data) => { |
| | const client = clients.get(sessionId); |
| | if (client && client.readyState === 1) { |
| | client.send(JSON.stringify({ |
| | ...data, |
| | sessionId |
| | })); |
| | } |
| | }; |
| |
|
| | export const broadcastToAll = (data) => { |
| | clients.forEach((client, sessionId) => { |
| | if (client.readyState === 1) { |
| | client.send(JSON.stringify({ |
| | ...data, |
| | sessionId |
| | })); |
| | } |
| | }); |
| | }; |