ayushagg12's picture
🐳 11/03 - 03:57 - help me to create a production based map tool for India where I can track my drivers real time where they are and capture coordinates from satelite using github repos with max stars
c00af66 verified
Raw
History Blame Contribute Delete
5.98 kB
/**
* Production Backend Server for India Driver Tracking
* GitHub: socketio/socket.io (60k stars), expressjs/express (65k stars)
*/
const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');
const Redis = require('ioredis');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
cors: {
origin: "*", // Configure for your domain in production
methods: ["GET", "POST"]
},
transports: ['websocket', 'polling'] // Fallback for Indian mobile networks
});
// Redis for real-time location storage (65k stars: redis/redis)
const redis = new Redis({
host: process.env.REDIS_HOST || 'localhost',
port: process.env.REDIS_PORT || 6379,
retryDelayOnFailover: 100
});
// Security middleware
app.use(helmet());
app.use(compression());
app.use(cors());
app.use(express.json({ limit: '10mb' }));
// Rate limiting for India mobile networks
const limiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP'
});
app.use('/api/', limiter);
// Active drivers storage (in-memory + Redis)
const activeDrivers = new Map();
// Socket.IO connection handling
io.on('connection', (socket) => {
console.log('Client connected:', socket.id);
// Driver authentication middleware
socket.on('driver:auth', async (data) => {
const { driverId, vehicleId, authToken } = data;
// Verify token here in production
socket.driverId = driverId;
socket.vehicleId = vehicleId;
socket.isDriver = true;
// Store socket mapping
await redis.hset(`driver:${driverId}`, 'socketId', socket.id, 'status', 'online');
socket.join(`driver:${driverId}`);
socket.join('all-drivers');
console.log(`Driver ${driverId} authenticated`);
socket.emit('auth:success', { message: 'Connected to tracking server' });
});
// Admin dashboard authentication
socket.on('admin:auth', (data) => {
socket.isAdmin = true;
socket.join('admins');
// Send current active drivers list
const driversList = Array.from(activeDrivers.values());
socket.emit('drivers:list', driversList);
});
// Real-time GPS update from driver app
socket.on('location:update', async (data) => {
if (!socket.isDriver) return;
const { lat, lng, accuracy, speed, heading, timestamp } = data;
const driverId = socket.driverId;
// Validate coordinates (India boundaries roughly)
if (lat < 6 || lat > 37 || lng < 68 || lng > 97) {
return socket.emit('error', { message: 'Invalid coordinates for India' });
}
const locationData = {
driverId,
vehicleId: socket.vehicleId,
lat,
lng,
accuracy: accuracy || 0,
speed: speed || 0,
heading: heading || 0,
timestamp: timestamp || Date.now(),
lastUpdate: Date.now()
};
// Update Redis (expires in 5 minutes if no update)
await redis.setex(`loc:${driverId}`, 300, JSON.stringify(locationData));
await redis.geoadd('drivers:geo', lng, lat, driverId);
// Update memory
activeDrivers.set(driverId, locationData);
// Broadcast to admins with throttling (every 2 seconds per driver)
socket.to('admins').emit('driver:moved', locationData);
});
// Handle driver status changes
socket.on('status:update', async (data) => {
if (!socket.isDriver) return;
const { status } = data; // 'available', 'busy', 'offline'
await redis.hset(`driver:${socket.driverId}`, 'status', status);
io.to('admins').emit('driver:status', {
driverId: socket.driverId,
status,
timestamp: Date.now()
});
});
// Admin requesting specific driver history
socket.on('admin:track-driver', async (driverId) => {
if (!socket.isAdmin) return;
socket.join(`track:${driverId}`);
const lastLoc = await redis.get(`loc:${driverId}`);
if (lastLoc) {
socket.emit('driver:location', JSON.parse(lastLoc));
}
});
// Handle disconnect
socket.on('disconnect', async () => {
if (socket.isDriver && socket.driverId) {
await redis.hset(`driver:${socket.driverId}`, 'status', 'offline');
await redis.expire(`driver:${socket.driverId}`, 3600); // Keep for 1 hour
activeDrivers.delete(socket.driverId);
io.to('admins').emit('driver:offline', { driverId: socket.driverId });
}
console.log('Client disconnected:', socket.id);
});
});
// REST API endpoints for historical data
app.get('/api/drivers/active', async (req, res) => {
try {
const drivers = [];
const keys = await redis.keys('loc:*');
for (const key of keys) {
const data = await redis.get(key);
if (data) drivers.push(JSON.parse(data));
}
res.json({ count: drivers.length, drivers });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Get drivers in specific radius (for India city operations)
app.get('/api/drivers/nearby', async (req, res) => {
const { lat, lng, radius = 10 } = req.query; // radius in km
try {
const nearby = await redis.georadius(
'drivers:geo',
parseFloat(lng),
parseFloat(lat),
parseFloat(radius),
'km',
'WITHCOORD',
'WITHDIST'
);
res.json({ nearby });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Health check
app.get('/health', (req, res) => {
res.json({
status: 'ok',
uptime: process.uptime(),
timestamp: new Date().toISOString(),
region: 'India'
});
});
const PORT = process.env.PORT || 3000;
httpServer.listen(PORT, () => {
console.log(`🚀 Production Tracking Server running on port ${PORT}`);
console.log(`📍 Optimized for India GPS tracking`);
});