import { Server as NetServer } from 'http'; import { Server as SocketIOServer } from 'socket.io'; import { NextApiRequest } from 'next'; import { NextApiResponse } from 'next'; export type NextApiResponseWithSocket = NextApiResponse & { socket: { server: NetServer & { io?: SocketIOServer; }; }; }; // Initialize Socket.IO server export const initSocketIO = (res: NextApiResponseWithSocket) => { if (!res.socket.server.io) { console.log('Initializing new Socket.IO server...'); // Create new Socket.IO server instance const io = new SocketIOServer(res.socket.server, { path: '/api/socket', addTrailingSlash: false, }); // Store Socket.IO server instance on the response object res.socket.server.io = io; // Set up Socket.IO event handlers io.on('connection', (socket) => { console.log(`Client connected: ${socket.id}`); // Handle client disconnection socket.on('disconnect', () => { console.log(`Client disconnected: ${socket.id}`); }); // Handle location updates socket.on('location:update', (data) => { console.log(`Received location update from ${socket.id}:`, data); // If a share token is provided, broadcast to that specific room if (data.shareToken) { socket.to(`share:${data.shareToken}`).emit('location:updated', { latitude: data.latitude, longitude: data.longitude, accuracy: data.accuracy, timestamp: data.timestamp || new Date().toISOString(), }); } }); // Join a location share room socket.on('share:join', (shareToken) => { if (shareToken) { socket.join(`share:${shareToken}`); console.log(`Client ${socket.id} joined room share:${shareToken}`); } }); // Leave a location share room socket.on('share:leave', (shareToken) => { if (shareToken) { socket.leave(`share:${shareToken}`); console.log(`Client ${socket.id} left room share:${shareToken}`); } }); }); } return res.socket.server.io; }; // Get the Socket.IO server instance export const getSocketIO = (res: NextApiResponseWithSocket) => { return res.socket.server.io || initSocketIO(res); };