javascript API

WebSocket Event Handler

Socket.io event handler with room management, authentication, rate limiting, and typed events for real-time features.

Apex Logic 0 copies
javascript
const { Server } = require('socket.io');
const jwt = require('jsonwebtoken');

function setupWebSocket(httpServer) {
    const io = new Server(httpServer, {
        cors: { origin: process.env.CLIENT_URL || '*', methods: ['GET', 'POST'] },
        pingInterval: 25000,
        pingTimeout: 60000,
        maxHttpBufferSize: 1e6, // 1MB
    });

    // Authentication middleware
    io.use((socket, next) => {
        const token = socket.handshake.auth.token;
        if (!token) return next(new Error('Authentication required'));

        try {
            const user = jwt.verify(token, process.env.JWT_SECRET);
            socket.user = user;
            next();
        } catch (err) {
            next(new Error('Invalid token'));
        }
    });

    // Rate limiting per socket
    const rateLimits = new Map();
    function checkRate(socketId, limit = 30, windowMs = 60000) {
        const now = Date.now();
        const record = rateLimits.get(socketId) || { count: 0, resetAt: now + windowMs };
        if (now > record.resetAt) { record.count = 0; record.resetAt = now + windowMs; }
        record.count++;
        rateLimits.set(socketId, record);
        return record.count <= limit;
    }

    io.on('connection', (socket) => {
        console.log(`User connected: ${socket.user.id}`);

        // Join user's personal room
        socket.join(`user:${socket.user.id}`);

        // Chat room management
        socket.on('join-room', (roomId) => {
            socket.join(roomId);
            socket.to(roomId).emit('user-joined', { userId: socket.user.id });
        });

        socket.on('leave-room', (roomId) => {
            socket.leave(roomId);
            socket.to(roomId).emit('user-left', { userId: socket.user.id });
        });

        // Message handling with rate limiting
        socket.on('message', (data) => {
            if (!checkRate(socket.id)) {
                return socket.emit('error', { message: 'Rate limit exceeded' });
            }
            const { roomId, content } = data;
            io.to(roomId).emit('message', {
                userId: socket.user.id,
                content,
                timestamp: new Date().toISOString(),
            });
        });

        socket.on('disconnect', () => {
            rateLimits.delete(socket.id);
            console.log(`User disconnected: ${socket.user.id}`);
        });
    });

    return io;
}

module.exports = setupWebSocket;

Tags

websocket socket.io realtime events

Related Snippets

javascript

JWT Authentication Middleware

javascript

MongoDB Connection with Retry

javascript

Express Global Error Handler

javascript

Rate Limiter with Sliding Window