tmc-v2/websocket.js

126 lines
4.0 KiB
JavaScript

const WebSocket = require('ws');
class WebSocketManager {
constructor() {
this.connectedDevices = new Map(); // deviceId -> WebSocket
this.wss = null;
}
initialize(server) {
this.wss = new WebSocket.Server({ server });
this.wss.on('connection', (ws) => {
console.log('New client connected');
ws.on('message', (message) => {
try {
const data = JSON.parse(message);
// Handle device identification
if (data.type === 'identification') {
this.connectedDevices.set(data.deviceId, ws);
console.log(`Device ${data.deviceId} (${data.model}) connected`);
// Send configuration immediately after identification
if (data.requestConfig) {
this.sendConfiguration(data.deviceId);
}
return;
}
if (data.type === 'redirect') {
console.log(`message ${data.amount}
${data.currencySymbol}
${data.id} `);
const ws = this.connectedDevices.get(data.id);
if (ws && ws.readyState === WebSocket.OPEN) {
message = JSON.stringify(data);
ws.send(message);
return true;
}
return;
}
if (data.type === 'message') {
console.log(`message ${data.content} `);
return;
}
// Handle other message types...
} catch (e) {
console.error('Error parsing message:', e);
}
});
ws.on('close', () => {
// Clean up disconnected devices
for (let [id, connection] of this.connectedDevices.entries()) {
if (connection === ws) {
this.connectedDevices.delete(id);
console.log(`Device ${id} disconnected`);
break;
}
}
});
ws.on('error', (error) => {
console.error('WebSocket error:', error);
});
});
}
sendToDevice(deviceId, message) {
const ws = this.connectedDevices.get(deviceId);
if (ws && ws.readyState === WebSocket.OPEN) {
if (typeof message !== 'string') {
message = JSON.stringify(message);
}
ws.send(message);
return true;
}
console.log(`Device ${deviceId} not connected`);
return false;
}
sendConfiguration(deviceId) {
// In a real app, you would fetch device-specific config from database
const config = {
type: "configuration",
deviceId: deviceId,
navItems: [{
navPage: "NAV_HOME",
navName: "PaymentZ",
icon: { type: "resource", value: "home" },
position: 0,
enabled: true
},
{
navPage: "NAV_SCAN",
navName: "ScannerZ",
icon: { type: "resource", value: "scan" },
position: 1,
enabled: true
},
],
timestamp: new Date().toISOString()
};
this.sendToDevice(deviceId, config);
}
broadcast(message) {
this.connectedDevices.forEach((ws, deviceId) => {
this.sendToDevice(deviceId, message);
});
}
getConnectedDevices() {
return Array.from(this.connectedDevices.keys());
}
}
module.exports = new WebSocketManager();