🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
Socket.IO Samples
Real-time bidirectional communication examples using Socket.IO with rooms, authentication, and advanced features
💻 Socket.IO Basic Chat Application javascript
🟢 simple
⭐⭐
Complete real-time chat application using Socket.IO with rooms, user management, and message history
⏱️ 15 min
🏷️ socket.io, chat, server, real-time
Prerequisites:
Node.js, Socket.IO basics
// Socket.IO Basic Chat Application
// Server-side implementation with Express
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const path = require('path');
const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
// Serve static files
app.use(express.static(path.join(__dirname, 'public')));
// Store active users and rooms
const users = new Map();
const rooms = new Map();
const messageHistory = new Map();
// Socket.IO connection handler
io.on('connection', (socket) => {
console.log(`User connected: ${socket.id}`);
// Handle user joining
socket.on('join', (data) => {
const { username, room } = data;
// Join specified room
socket.join(room);
// Store user information
users.set(socket.id, {
id: socket.id,
username,
room,
joinedAt: new Date()
});
// Initialize room if not exists
if (!rooms.has(room)) {
rooms.set(room, new Set());
messageHistory.set(room, []);
}
rooms.get(room).add(socket.id);
// Notify others in the room
socket.to(room).emit('user_joined', {
username,
userId: socket.id,
timestamp: new Date()
});
// Send room info to the user
const roomUsers = Array.from(rooms.get(room))
.map(id => users.get(id))
.filter(Boolean)
.map(user => ({
id: user.id,
username: user.username
}));
socket.emit('room_info', {
room,
users: roomUsers,
messages: messageHistory.get(room) || []
});
console.log(`${username} joined room: ${room}`);
});
// Handle chat messages
socket.on('send_message', (data) => {
const user = users.get(socket.id);
if (!user) return;
const message = {
id: generateMessageId(),
userId: socket.id,
username: user.username,
room: user.room,
message: data.message,
timestamp: new Date()
};
// Store message in history
if (!messageHistory.has(user.room)) {
messageHistory.set(user.room, []);
}
messageHistory.get(user.room).push(message);
// Limit message history
const history = messageHistory.get(user.room);
if (history.length > 100) {
history.splice(0, history.length - 100);
}
// Broadcast message to room
io.to(user.room).emit('receive_message', message);
console.log(`Message in ${user.room}: ${user.username}: ${data.message}`);
});
// Handle typing indicators
socket.on('typing_start', (data) => {
const user = users.get(socket.id);
if (!user) return;
socket.to(user.room).emit('user_typing', {
username: user.username,
typing: true
});
});
socket.on('typing_stop', (data) => {
const user = users.get(socket.id);
if (!user) return;
socket.to(user.room).emit('user_typing', {
username: user.username,
typing: false
});
});
// Handle private messages
socket.on('private_message', (data) => {
const sender = users.get(socket.id);
if (!sender) return;
const message = {
id: generateMessageId(),
from: socket.id,
fromUsername: sender.username,
to: data.toUserId,
message: data.message,
timestamp: new Date(),
private: true
};
// Send to recipient
io.to(data.toUserId).emit('private_message', message);
// Send confirmation to sender
socket.emit('message_sent', message);
console.log(`Private message from ${sender.username} to ${data.toUserId}`);
});
// Handle room creation
socket.on('create_room', (data) => {
const { roomName, password } = data;
const user = users.get(socket.id);
if (!user) return;
// Create new room
if (!rooms.has(roomName)) {
rooms.set(roomName, new Set());
messageHistory.set(roomName, []);
}
// Join creator to the room
socket.join(roomName);
rooms.get(roomName).add(socket.id);
socket.emit('room_created', {
roomName,
hasPassword: !!password
});
console.log(`Room created: ${roomName} by ${user.username}`);
});
// Handle leaving room
socket.on('leave_room', () => {
const user = users.get(socket.id);
if (!user) return;
socket.leave(user.room);
// Remove user from room
if (rooms.has(user.room)) {
rooms.get(user.room).delete(socket.id);
// Notify others
socket.to(user.room).emit('user_left', {
username: user.username,
userId: socket.id,
timestamp: new Date()
});
// Clean up empty rooms
if (rooms.get(user.room).size === 0) {
rooms.delete(user.room);
messageHistory.delete(user.room);
}
}
// Clear user data
users.delete(socket.id);
socket.emit('left_room');
console.log(`${user.username} left room`);
});
// Handle getting room list
socket.on('get_rooms', () => {
const roomList = Array.from(rooms.keys()).map(roomName => ({
name: roomName,
userCount: rooms.get(roomName).size
}));
socket.emit('rooms_list', roomList);
});
// Handle disconnection
socket.on('disconnect', () => {
const user = users.get(socket.id);
if (user) {
// Notify others in the room
if (rooms.has(user.room)) {
rooms.get(user.room).delete(socket.id);
socket.to(user.room).emit('user_left', {
username: user.username,
userId: socket.id,
timestamp: new Date()
});
// Clean up empty rooms
if (rooms.get(user.room).size === 0) {
rooms.delete(user.room);
messageHistory.delete(user.room);
}
}
users.delete(socket.id);
console.log(`${user.username} disconnected`);
} else {
console.log(`Anonymous user disconnected: ${socket.id}`);
}
});
});
// Utility function to generate message ID
function generateMessageId() {
return Math.random().toString(36).substr(2, 9);
}
// HTTP route for root
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// Start server
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Socket.IO chat server running on port ${PORT}`);
});
💻 Socket.IO React Client Component typescript
🟡 intermediate
⭐⭐⭐
Modern React component using Socket.IO client with hooks for real-time communication
⏱️ 25 min
🏷️ socket.io, react, client, typescript
Prerequisites:
React, TypeScript, Socket.IO client
// Socket.IO React Client Component
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { io, Socket } from 'socket.io-client';
import './ChatApp.css';
interface Message {
id: string;
username: string;
message: string;
timestamp: Date;
userId: string;
private?: boolean;
from?: string;
fromUsername?: string;
to?: string;
}
interface User {
id: string;
username: string;
}
interface Room {
name: string;
userCount: number;
}
const ChatApp: React.FC = () => {
const [socket, setSocket] = useState<Socket | null>(null);
const [username, setUsername] = useState('');
const [currentRoom, setCurrentRoom] = useState('');
const [messages, setMessages] = useState<Message[]>([]);
const [users, setUsers] = useState<User[]>([]);
const [rooms, setRooms] = useState<Room[]>([]);
const [inputMessage, setInputMessage] = useState('');
const [isConnected, setIsConnected] = useState(false);
const [isTyping, setIsTyping] = useState(false);
const [typingUsers, setTypingUsers] = useState<string[]>([]);
const [showRoomList, setShowRoomList] = useState(false);
const [newRoomName, setNewRoomName] = useState('');
const [targetUser, setTargetUser] = useState('');
const [privateMessage, setPrivateMessage] = useState('');
const messagesEndRef = useRef<HTMLDivElement>(null);
const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
// Initialize Socket.IO connection
useEffect(() => {
const newSocket = io(process.env.REACT_APP_SOCKET_URL || 'http://localhost:3000', {
transports: ['websocket', 'polling'],
upgrade: true
});
setSocket(newSocket);
newSocket.on('connect', () => {
setIsConnected(true);
console.log('Connected to Socket.IO server');
});
newSocket.on('disconnect', () => {
setIsConnected(false);
console.log('Disconnected from Socket.IO server');
});
return () => {
newSocket.disconnect();
};
}, []);
// Handle receiving messages
useEffect(() => {
if (!socket) return;
socket.on('receive_message', (message: Message) => {
setMessages(prev => [...prev, message]);
});
socket.on('private_message', (message: Message) => {
setMessages(prev => [...prev, message]);
});
socket.on('room_info', (data: { room: string; users: User[]; messages: Message[] }) => {
setUsers(data.users);
setMessages(data.messages);
});
socket.on('rooms_list', (roomList: Room[]) => {
setRooms(roomList);
});
socket.on('user_joined', (data: { username: string; userId: string }) => {
setUsers(prev => [...prev, { id: data.userId, username: data.username }]);
});
socket.on('user_left', (data: { username: string; userId: string }) => {
setUsers(prev => prev.filter(user => user.id !== data.userId));
});
socket.on('user_typing', (data: { username: string; typing: boolean }) => {
setTypingUsers(prev => {
if (data.typing) {
return [...prev.filter(u => u !== data.username), data.username];
} else {
return prev.filter(u => u !== data.username);
}
});
});
socket.on('room_created', (data: { roomName: string; hasPassword: boolean }) => {
setRooms(prev => [...prev, { name: data.roomName, userCount: 1 }]);
});
return () => {
socket.off('receive_message');
socket.off('private_message');
socket.off('room_info');
socket.off('rooms_list');
socket.off('user_joined');
socket.off('user_left');
socket.off('user_typing');
socket.off('room_created');
};
}, [socket]);
// Auto-scroll to bottom
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
// Join room
const joinRoom = useCallback(() => {
if (socket && username && currentRoom) {
socket.emit('join', { username, room: currentRoom });
socket.emit('get_rooms');
}
}, [socket, username, currentRoom]);
// Send message
const sendMessage = useCallback(() => {
if (socket && inputMessage.trim()) {
socket.emit('send_message', { message: inputMessage.trim() });
setInputMessage('');
stopTyping();
}
}, [socket, inputMessage]);
// Send private message
const sendPrivateMessage = useCallback(() => {
if (socket && targetUser && privateMessage.trim()) {
const targetUserObj = users.find(u => u.username === targetUser);
if (targetUserObj) {
socket.emit('private_message', {
toUserId: targetUserObj.id,
message: privateMessage.trim()
});
setPrivateMessage('');
}
}
}, [socket, targetUser, privateMessage, users]);
// Create new room
const createRoom = useCallback(() => {
if (socket && newRoomName.trim()) {
socket.emit('create_room', { roomName: newRoomName.trim() });
setNewRoomName('');
}
}, [socket, newRoomName]);
// Typing handlers
const startTyping = useCallback(() => {
if (!isTyping && socket) {
setIsTyping(true);
socket.emit('typing_start');
if (typingTimeoutRef.current) {
clearTimeout(typingTimeoutRef.current);
}
typingTimeoutRef.current = setTimeout(() => {
stopTyping();
}, 3000);
}
}, [isTyping, socket]);
const stopTyping = useCallback(() => {
if (isTyping && socket) {
setIsTyping(false);
socket.emit('typing_stop');
if (typingTimeoutRef.current) {
clearTimeout(typingTimeoutRef.current);
typingTimeoutRef.current = null;
}
}
}, [isTyping, socket]);
// Handle input changes
const handleMessageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputMessage(e.target.value);
if (e.target.value.trim()) {
startTyping();
} else {
stopTyping();
}
};
const handleKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
e.preventDefault();
sendMessage();
}
};
return (
<div className="chat-app">
{!username ? (
<div className="login-form">
<h2>Join Chat</h2>
<input
type="text"
placeholder="Enter your username"
value={username}
onChange={(e) => setUsername(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && setUsername(e.target.value)}
/>
</div>
) : !currentRoom ? (
<div className="room-selection">
<h2>Welcome, {username}!</h2>
<div className="join-room">
<h3>Join Existing Room</h3>
<input
type="text"
placeholder="Room name"
value={currentRoom}
onChange={(e) => setCurrentRoom(e.target.value)}
/>
<button onClick={joinRoom} disabled={!currentRoom}>
Join Room
</button>
</div>
<div className="create-room">
<h3>Create New Room</h3>
<input
type="text"
placeholder="New room name"
value={newRoomName}
onChange={(e) => setNewRoomName(e.target.value)}
/>
<button onClick={createRoom} disabled={!newRoomName}>
Create Room
</button>
</div>
<div className="room-list">
<h3>Available Rooms</h3>
{rooms.map(room => (
<div key={room.name} className="room-item">
<span>{room.name}</span>
<span className="user-count">{room.userCount} users</span>
<button onClick={() => {
setCurrentRoom(room.name);
setTimeout(joinRoom, 100);
}}>
Join
</button>
</div>
))}
</div>
</div>
) : (
<div className="chat-container">
<div className="chat-header">
<div className="connection-status">
<span className={isConnected ? 'connected' : 'disconnected'} />
{isConnected ? 'Connected' : 'Disconnected'}
</div>
<div className="room-info">
Room: {currentRoom}
</div>
<div className="user-info">
{username}
</div>
</div>
<div className="chat-body">
<div className="sidebar">
<div className="users-section">
<h3>Users in Room</h3>
{users.map(user => (
<div key={user.id} className="user-item">
{user.username}
{user.username !== username && (
<button
onClick={() => setTargetUser(user.username)}
className="pm-btn"
>
PM
</button>
)}
</div>
))}
</div>
{targetUser && (
<div className="private-message">
<h4>Private Message to {targetUser}</h4>
<input
type="text"
placeholder="Type private message..."
value={privateMessage}
onChange={(e) => setPrivateMessage(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendPrivateMessage()}
/>
<button onClick={sendPrivateMessage} disabled={!privateMessage}>
Send
</button>
</div>
)}
</div>
<div className="main-chat">
<div className="messages-container">
{messages.map((message, index) => (
<div
key={message.id || index}
className={`message ${message.userId === socket?.id ? 'own' : ''} ${message.private ? 'private' : ''}`}
>
<div className="message-header">
<span className="message-username">
{message.fromUsername || message.username}
</span>
<span className="message-timestamp">
{new Date(message.timestamp).toLocaleTimeString()}
</span>
{message.private && <span className="private-indicator">🔒</span>}
</div>
<div className="message-content">
{message.message}
</div>
</div>
))}
{typingUsers.length > 0 && (
<div className="typing-indicator">
{typingUsers.join(', ')} {typingUsers.length === 1 ? 'is' : 'are'} typing...
</div>
)}
<div ref={messagesEndRef} />
</div>
<div className="message-input">
<input
type="text"
placeholder="Type a message..."
value={inputMessage}
onChange={handleMessageChange}
onKeyPress={handleKeyPress}
disabled={!isConnected}
/>
<button
onClick={sendMessage}
disabled={!inputMessage.trim() || !isConnected}
>
Send
</button>
</div>
</div>
</div>
</div>
)}
</div>
);
};
export default ChatApp;
💻 Advanced Socket.IO Features javascript
🔴 complex
⭐⭐⭐⭐⭐
Advanced Socket.IO patterns including authentication, namespaces, adapters, and scalability
⏱️ 45 min
🏷️ socket.io, advanced, scaling, authentication
Prerequisites:
Socket.IO, Redis, JWT, Node.js advanced
// Advanced Socket.IO Features Implementation
// Including authentication, namespaces, rooms, and Redis adapter
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const redis = require('socket.io-redis');
const jwt = require('jsonwebtoken');
const rateLimit = require('express-rate-limit');
const helmet = require('helmet');
const app = express();
const server = http.createServer(app);
// Security middleware
app.use(helmet());
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);
app.use(express.json());
// Configure Socket.IO with advanced options
const io = socketIo(server, {
cors: {
origin: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'],
methods: ['GET', 'POST'],
credentials: true
},
transports: ['websocket', 'polling'],
pingTimeout: 60000,
pingInterval: 25000,
maxHttpBufferSize: 1e8, // 100 MB
perMessageDeflate: {
threshold: 1024
}
});
// Redis adapter for multi-server scaling
if (process.env.REDIS_URL) {
io.adapter(redis(process.env.REDIS_URL));
console.log('Redis adapter enabled for scaling');
}
// JWT Secret
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
// Authentication middleware for Socket.IO
const authenticateSocket = async (socket, next) => {
try {
const token = socket.handshake.auth.token ||
socket.handshake.headers.authorization?.replace('Bearer ', '');
if (!token) {
return next(new Error('Authentication token required'));
}
const decoded = jwt.verify(token, JWT_SECRET);
socket.userId = decoded.userId;
socket.username = decoded.username;
socket.role = decoded.role || 'user';
// Add custom properties
socket.join(`user_${socket.userId}`); // Personal room for targeted messages
next();
} catch (error) {
console.error('Socket authentication error:', error);
next(new Error('Invalid authentication token'));
}
};
// Apply authentication middleware
io.use(authenticateSocket);
// Main namespace - general chat and notifications
io.on('connection', (socket) => {
console.log(`User connected: ${socket.username} (${socket.userId}) with role: ${socket.role}`);
// Track user connection
trackUserConnection(socket);
// Handle joining rooms with permission checking
socket.on('join_room', async (data) => {
try {
const { roomId, password } = data;
// Verify room permissions
const hasPermission = await checkRoomPermission(socket, roomId);
if (!hasPermission) {
return socket.emit('error', { message: 'Permission denied' });
}
// Join room
await socket.join(roomId);
socket.currentRoom = roomId;
// Notify others
socket.to(roomId).emit('user_joined', {
userId: socket.userId,
username: socket.username,
role: socket.role,
timestamp: new Date()
});
// Send room data
const roomData = await getRoomData(roomId);
socket.emit('room_joined', roomData);
console.log(`${socket.username} joined room: ${roomId}`);
} catch (error) {
socket.emit('error', { message: 'Failed to join room' });
}
});
// Handle file sharing with progress tracking
socket.on('upload_file', async (data) => {
try {
const { roomId, fileName, fileSize, fileData } = data;
// Check file size limits
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
if (fileSize > MAX_FILE_SIZE) {
return socket.emit('upload_error', { message: 'File too large' });
}
// Process file upload in chunks
const fileId = generateId();
let uploadedBytes = 0;
const chunkSize = 1024 * 1024; // 1MB chunks
socket.emit('upload_started', { fileId, fileName, totalSize: fileSize });
for (let i = 0; i < fileData.length; i += chunkSize) {
const chunk = fileData.slice(i, i + chunkSize);
uploadedBytes += chunk.length;
// Process chunk (save to storage, etc.)
await processFileChunk(fileId, chunk, i);
// Send progress update
socket.emit('upload_progress', {
fileId,
progress: Math.round((uploadedBytes / fileSize) * 100)
});
// Simulate processing delay
await new Promise(resolve => setTimeout(resolve, 100));
}
// Notify room about new file
const fileUrl = `/uploads/${fileId}/${fileName}`;
socket.to(roomId).emit('file_shared', {
fileId,
fileName,
fileSize,
fileUrl,
sharedBy: socket.username,
timestamp: new Date()
});
socket.emit('upload_completed', { fileId, fileUrl });
} catch (error) {
socket.emit('upload_error', { message: 'Upload failed' });
}
});
// Handle voice call signaling
socket.on('voice_call', async (data) => {
const { targetUserId, callType } = data; // callType: 'audio' or 'video'
const callId = generateId();
const callData = {
callId,
callerId: socket.userId,
callerUsername: socket.username,
callType,
roomId: `call_${callId}`,
timestamp: new Date()
};
// Create private room for the call
await socket.join(callData.roomId);
await io.to(targetUserId).socketsJoin(callData.roomId);
// Send call invitation to target user
io.to(targetUserId).emit('call_invitation', callData);
// Handle call responses
socket.on('call_response', (response) => {
const { accepted, callId: responseCallId } = response;
io.to(`call_${responseCallId}`).emit('call_response', {
accepted,
respondedBy: socket.userId,
respondedByUsername: socket.username
});
if (!accepted) {
// Clean up call room
io.in(`call_${responseCallId}`).socketsLeave(`call_${responseCallId}`);
}
});
// Handle WebRTC signaling
socket.on('ice_candidate', (data) => {
socket.to(`call_${data.callId}`).emit('ice_candidate', {
candidate: data.candidate,
fromUserId: socket.userId
});
});
socket.on('offer', (data) => {
socket.to(`call_${data.callId}`).emit('offer', {
offer: data.offer,
fromUserId: socket.userId
});
});
socket.on('answer', (data) => {
socket.to(`call_${data.callId}`).emit('answer', {
answer: data.answer,
fromUserId: socket.userId
});
});
console.log(`Voice call initiated: ${socket.username} -> ${targetUserId}`);
});
// Handle admin commands
if (socket.role === 'admin') {
socket.on('admin_command', async (data) => {
const { command, targetUserId, roomId, params } = data;
switch (command) {
case 'kick_user':
await kickUser(targetUserId, roomId);
break;
case 'ban_user':
await banUser(targetUserId);
break;
case 'mute_user':
await muteUser(targetUserId, roomId, params.duration);
break;
case 'clear_room':
await clearRoomMessages(roomId);
break;
case 'server_stats':
const stats = await getServerStats();
socket.emit('server_stats', stats);
break;
}
});
}
// Handle disconnection
socket.on('disconnect', (reason) => {
console.log(`User disconnected: ${socket.username} (${reason})`);
// Clean up user data
if (socket.currentRoom) {
socket.to(socket.currentRoom).emit('user_left', {
userId: socket.userId,
username: socket.username,
timestamp: new Date()
});
}
removeUserConnection(socket);
});
});
// Admin namespace - administrative operations
const adminNamespace = io.of('/admin');
adminNamespace.use((socket, next) => {
// Enhanced authentication for admin namespace
const token = socket.handshake.auth.token;
try {
const decoded = jwt.verify(token, JWT_SECRET);
if (decoded.role !== 'admin') {
return next(new Error('Admin access required'));
}
socket.userId = decoded.userId;
socket.username = decoded.username;
socket.role = 'admin';
next();
} catch (error) {
next(new Error('Invalid admin credentials'));
}
});
adminNamespace.on('connection', (socket) => {
console.log(`Admin connected: ${socket.username}`);
// Real-time server monitoring
socket.on('get_stats', async () => {
const stats = await getServerStats();
socket.emit('stats', stats);
});
// System announcements
socket.on('broadcast_announcement', (data) => {
const { message, type = 'info', targetRole } = data;
// Broadcast to all users or specific role
if (targetRole) {
io.to(`role_${targetRole}`).emit('announcement', {
message,
type,
timestamp: new Date(),
fromAdmin: socket.username
});
} else {
io.emit('announcement', {
message,
type,
timestamp: new Date(),
fromAdmin: socket.username
});
}
});
});
// Notification namespace - system notifications
const notificationNamespace = io.of('/notifications');
notificationNamespace.use(authenticateSocket);
notificationNamespace.on('connection', (socket) => {
console.log(`Notification client connected: ${socket.username}`);
// User preferences
socket.on('update_preferences', (preferences) => {
updateUserNotificationPreferences(socket.userId, preferences);
});
// Mark notifications as read
socket.on('mark_read', (notificationIds) => {
markNotificationsAsRead(socket.userId, notificationIds);
});
});
// Utility functions
function generateId() {
return Math.random().toString(36).substr(2, 9) + Date.now().toString(36);
}
async function checkRoomPermission(socket, roomId) {
// Implement room permission logic
// Check database, user roles, etc.
return true; // Simplified for example
}
async function getRoomData(roomId) {
// Fetch room data from database
return {
roomId,
name: roomId,
users: [], // Array of users in room
messages: [], // Recent messages
permissions: {
canSendMessages: true,
canSendFiles: true,
canInviteUsers: true
}
};
}
async function processFileChunk(fileId, chunk, offset) {
// Process and store file chunk
// This would integrate with cloud storage, database, etc.
await new Promise(resolve => setTimeout(resolve, 50));
}
async function kickUser(userId, roomId) {
const socket = [...io.sockets.sockets.values()].find(s => s.userId === userId);
if (socket) {
socket.to(roomId).emit('user_kicked', { userId, username: socket.username });
socket.leave(roomId);
socket.emit('kicked', { roomId, reason: 'Kicked by admin' });
}
}
async function banUser(userId) {
// Implement user ban logic
// Update database, disconnect user, prevent reconnection
}
async function muteUser(userId, roomId, duration) {
// Implement user mute logic
// Store mute information with expiration
}
async function clearRoomMessages(roomId) {
// Clear all messages in a room
// This would update the database
io.to(roomId).emit('messages_cleared', { roomId });
}
async function getServerStats() {
const sockets = await io.fetchSockets();
return {
connectedUsers: sockets.length,
rooms: await getRoomCount(),
messages: await getMessageCount(),
uptime: process.uptime(),
memory: process.memoryUsage(),
timestamp: new Date()
};
}
function trackUserConnection(socket) {
// Track user connection in database
// Store connection info, last seen, etc.
}
function removeUserConnection(socket) {
// Remove user connection tracking
// Update last seen, clean up resources
}
function updateUserNotificationPreferences(userId, preferences) {
// Update user notification preferences in database
}
function markNotificationsAsRead(userId, notificationIds) {
// Mark notifications as read in database
}
// Broadcast system notifications
function broadcastNotification(data) {
notificationNamespace.emit('notification', {
...data,
timestamp: new Date()
});
}
// Send targeted notification to specific user
function sendUserNotification(userId, data) {
notificationNamespace.to(`user_${userId}`).emit('notification', {
...data,
timestamp: new Date()
});
}
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully');
server.close(() => {
console.log('Server closed');
process.exit(0);
});
});
const PORT = process.env.PORT || 3001;
server.listen(PORT, () => {
console.log(`Advanced Socket.IO server running on port ${PORT}`);
});
module.exports = { app, server, io, broadcastNotification, sendUserNotification };