feat: implement real-time chat with Socket.IO
Implemented WebSocket-based real-time messaging for both event rooms and private match chats using Socket.IO with comprehensive test coverage. Backend changes: - Installed socket.io@4.8.1 for WebSocket server - Created Socket.IO server with JWT authentication middleware - Implemented event room management (join/leave/messages) - Added active users tracking with real-time updates - Implemented private match room messaging - Integrated Socket.IO with Express HTTP server - Messages are persisted to PostgreSQL via Prisma - Added 12 comprehensive unit tests (89.13% coverage) Frontend changes: - Installed socket.io-client for WebSocket connections - Created socket service layer for connection management - Updated EventChatPage with real-time messaging - Updated MatchChatPage with real-time private chat - Added connection status indicators (● Connected/Disconnected) - Disabled message input when not connected Infrastructure: - Updated nginx config to proxy WebSocket connections at /socket.io - Added Upgrade and Connection headers for WebSocket support - Set long timeouts (7d) for persistent WebSocket connections Key features: - JWT-authenticated socket connections - Room-based architecture for events and matches - Real-time message broadcasting - Active users list with automatic updates - Automatic cleanup on disconnect - Message persistence in database Test coverage: - 12 tests passing (authentication, event rooms, match rooms, disconnect, errors) - Socket.IO module: 89.13% statements, 81.81% branches, 91.66% functions - Overall coverage: 81.19% Phase 1, Step 4 completed. Ready for Phase 2 (Core Features).
This commit is contained in:
56
frontend/src/services/socket.js
Normal file
56
frontend/src/services/socket.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import { io } from 'socket.io-client';
|
||||
|
||||
const SOCKET_URL = 'http://localhost:8080';
|
||||
|
||||
let socket = null;
|
||||
|
||||
export function connectSocket() {
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
if (!token) {
|
||||
console.error('No token found for socket connection');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (socket && socket.connected) {
|
||||
return socket;
|
||||
}
|
||||
|
||||
socket = io(SOCKET_URL, {
|
||||
auth: {
|
||||
token,
|
||||
},
|
||||
reconnection: true,
|
||||
reconnectionAttempts: 5,
|
||||
reconnectionDelay: 1000,
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
console.log('✅ Socket connected:', socket.id);
|
||||
});
|
||||
|
||||
socket.on('disconnect', (reason) => {
|
||||
console.log('❌ Socket disconnected:', reason);
|
||||
});
|
||||
|
||||
socket.on('connect_error', (error) => {
|
||||
console.error('Socket connection error:', error.message);
|
||||
});
|
||||
|
||||
socket.on('error', (error) => {
|
||||
console.error('Socket error:', error);
|
||||
});
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
export function disconnectSocket() {
|
||||
if (socket) {
|
||||
socket.disconnect();
|
||||
socket = null;
|
||||
}
|
||||
}
|
||||
|
||||
export function getSocket() {
|
||||
return socket;
|
||||
}
|
||||
Reference in New Issue
Block a user