diff options
Diffstat (limited to 'app/src/server/socket.ts')
-rw-r--r-- | app/src/server/socket.ts | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/app/src/server/socket.ts b/app/src/server/socket.ts new file mode 100644 index 0000000..a65ed7e --- /dev/null +++ b/app/src/server/socket.ts @@ -0,0 +1,114 @@ +import { Server } from "socket.io"; +import { createServer } from "http"; +import { prisma } from "./db"; + +// Function to generate a share token +function generateShareToken(length = 8) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let result = ''; + for (let i = 0; i < length; i++) { + result += chars.charAt(Math.floor(Math.random() * chars.length)); + } + return result; +} + +// Store active connections +const activeUsers = new Map<string, string>(); + +const httpServer = createServer(); +const io = new Server(httpServer, { + cors: { + origin: process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000", + methods: ["GET", "POST"], + }, +}); + +// Set up Socket.IO event handlers +io.on('connection', (socket) => { + console.log(`New client connected: ${socket.id}`); + + // Handle user login/registration + socket.on('user:register', (userId: string) => { + console.log(`User registered: ${userId} (Socket: ${socket.id})`); + activeUsers.set(userId, socket.id); + // Broadcast updated user list + io.emit('users:update', Array.from(activeUsers.keys())); + }); + + // Handle location updates + socket.on('location:update', (data: { + userId: string; + latitude: number; + longitude: number; + accuracy?: number; + timestamp?: string; + }) => { + console.log(`Location update from ${data.userId}: ${data.latitude}, ${data.longitude}`); + // Add timestamp if not provided + if (!data.timestamp) { + data.timestamp = new Date().toISOString(); + } + // Broadcast to all connected clients + io.emit('location:broadcast', data); + }); + + // Handle direct messages or location shares + socket.on('location:share', (data: { + fromUserId: string; + toUserId: string; + latitude: number; + longitude: number; + accuracy?: number; + }) => { + console.log(`Location share from ${data.fromUserId} to ${data.toUserId}`); + const targetSocketId = activeUsers.get(data.toUserId); + + if (targetSocketId) { + // Send to specific user + io.to(targetSocketId).emit('location:shared', { + fromUserId: data.fromUserId, + latitude: data.latitude, + longitude: data.longitude, + accuracy: data.accuracy, + timestamp: new Date().toISOString() + }); + } + }); + + // Handle location sharing via token + socket.on('share:join', (shareToken: string) => { + if (shareToken) { + socket.join(`share:${shareToken}`); + console.log(`Client ${socket.id} joined room share:${shareToken}`); + } + }); + + socket.on('share:leave', (shareToken: string) => { + if (shareToken) { + socket.leave(`share:${shareToken}`); + console.log(`Client ${socket.id} left room share:${shareToken}`); + } + }); + + // Handle disconnect + socket.on('disconnect', () => { + console.log(`Client disconnected: ${socket.id}`); + // Remove user from active users + for (const [userId, socketId] of activeUsers.entries()) { + if (socketId === socket.id) { + activeUsers.delete(userId); + break; + } + } + // Broadcast updated user list + io.emit('users:update', Array.from(activeUsers.keys())); + }); +}); + +const PORT = parseInt(process.env.SOCKET_PORT || "3001", 10); + +export const startSocketServer = () => { + httpServer.listen(PORT, () => { + console.log(`Socket.IO server running on port ${PORT}`); + }); +};
\ No newline at end of file |