function initializeSocketHandlers(io) { io.on('connection', (socket) => { // Get real client IP from proxy headers (nginx forwarded headers) const clientIP = socket.handshake.headers['x-forwarded-for']?.split(',')[0]?.trim() || socket.handshake.headers['x-real-ip'] || socket.handshake.address || socket.request.connection.remoteAddress || 'unknown'; console.log(`Client connected: ${socket.id} from IP: ${clientIP}`); // Join device-specific rooms for targeted updates socket.on('join_device_room', (deviceId) => { socket.join(`device_${deviceId}`); console.log(`Client ${socket.id} (IP: ${clientIP}) joined device room: device_${deviceId}`); }); // 🔒 SECURITY: Join tenant-specific room for multi-tenant isolation socket.on('join_tenant_room', (tenantId) => { socket.join(`tenant_${tenantId}`); console.log(`Client ${socket.id} (IP: ${clientIP}) joined tenant room: tenant_${tenantId}`); }); // Join dashboard room for general updates socket.on('join_dashboard', () => { socket.join('dashboard'); console.log(`Client ${socket.id} (IP: ${clientIP}) joined dashboard room`); }); // Leave rooms socket.on('leave_device_room', (deviceId) => { socket.leave(`device_${deviceId}`); console.log(`Client ${socket.id} (IP: ${clientIP}) left device room: device_${deviceId}`); }); socket.on('leave_tenant_room', (tenantId) => { socket.leave(`tenant_${tenantId}`); console.log(`Client ${socket.id} (IP: ${clientIP}) left tenant room: tenant_${tenantId}`); }); socket.on('leave_dashboard', () => { socket.leave('dashboard'); console.log(`Client ${socket.id} (IP: ${clientIP}) left dashboard room`); }); // Handle client disconnect socket.on('disconnect', () => { console.log(`Client disconnected: ${socket.id} from IP: ${clientIP}`); }); // Send current status on connect socket.emit('connection_status', { status: 'connected', timestamp: new Date().toISOString(), clientId: socket.id }); }); // Helper functions to emit events to specific rooms io.emitToDevice = function(deviceId, event, data) { io.to(`device_${deviceId}`).emit(event, data); }; io.emitToTenant = function(tenantId, event, data) { io.to(`tenant_${tenantId}`).emit(event, data); }; io.emitToDashboard = function(event, data) { io.to('dashboard').emit(event, data); }; console.log('Socket.IO handlers initialized'); } module.exports = { initializeSocketHandlers };