const { createServer } = require('http'); const { parse } = require('url'); const next = require('next'); const { Server } = require('socket.io'); const dev = process.env.NODE_ENV !== 'production'; const hostname = 'localhost'; const port = parseInt(process.env.PORT || '3000', 10); const socketPort = parseInt(process.env.SOCKET_PORT || '3001', 10); // Create Next.js app const app = next({ dev, hostname, port }); const handler = app.getRequestHandler(); // Create HTTP server for socket events const httpServer = createServer((req, res) => { const url = parse(req.url, true); if (url.pathname === '/file:uploaded' && req.method === 'POST') { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { try { const fileData = JSON.parse(body); io.emit('file:uploaded', fileData); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true })); } catch (error) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: false, error: 'Invalid data' })); } }); } else if (url.pathname === '/file:deleted' && req.method === 'POST') { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { try { const data = JSON.parse(body); io.emit('file:deleted', data); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true })); } catch (error) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: false, error: 'Invalid data' })); } }); } else if (url.pathname === '/file:visibility:changed' && req.method === 'POST') { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { try { const data = JSON.parse(body); io.emit('file:visibility:changed', data); res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true })); } catch (error) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: false, error: 'Invalid data' })); } }); } else { res.writeHead(404, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: false, error: 'Not found' })); } }); // Create Socket.IO server const io = new Server(httpServer, { cors: { origin: process.env.NEXTAUTH_URL || `http://${hostname}:${port}`, methods: ['GET', 'POST'], }, }); let userCount = 0; io.on('connection', (socket) => { userCount++; io.emit('user:count', userCount); console.log(`User connected. Total users: ${userCount}`); // Handle file upload events (from client) socket.on('file:upload', (data) => { socket.broadcast.emit('file:uploaded', data); console.log('File uploaded:', data.filename); }); // Handle file delete events (from client) socket.on('file:delete', (data) => { socket.broadcast.emit('file:deleted', data); console.log('File deleted:', data.id); }); // Handle file visibility toggle events (from client) socket.on('file:toggle:visibility', (data) => { socket.broadcast.emit('file:visibility:changed', data); console.log('File visibility changed:', data.id, data.isVisible); }); socket.on('disconnect', () => { userCount--; io.emit('user:count', userCount); console.log(`User disconnected. Total users: ${userCount}`); }); }); app.prepare().then(() => { // Start Next.js server createServer(async (req, res) => { try { const parsedUrl = parse(req.url, true); await handler(req, res, parsedUrl); } catch (err) { console.error('Error occurred handling', req.url, err); res.statusCode = 500; res.end('internal server error'); } }) .once('error', (err) => { console.error(err); process.exit(1); }) .listen(port, () => { console.log(`> Ready on http://${hostname}:${port}`); }); // Start Socket.IO server httpServer.listen(socketPort, () => { console.log(`> Socket.IO server ready on http://${hostname}:${socketPort}`); }); });