| 35 | * If REDIS_URL is configured, adds Redis adapter for cross-pod broadcasting. |
| 36 | */ |
| 37 | export async function createSocketIOServer(httpServer: HttpServer): Promise<Server> { |
| 38 | const allowedOrigins = getAllowedOrigins() |
| 39 | |
| 40 | const io = new Server(httpServer, { |
| 41 | cors: { |
| 42 | origin: allowedOrigins, |
| 43 | methods: ['GET', 'POST', 'OPTIONS'], |
| 44 | allowedHeaders: ['Content-Type', 'Authorization', 'Cookie', 'socket.io'], |
| 45 | credentials: true, |
| 46 | }, |
| 47 | transports: ['websocket', 'polling'], |
| 48 | allowEIO3: true, |
| 49 | pingTimeout: PING_TIMEOUT_MS, |
| 50 | pingInterval: PING_INTERVAL_MS, |
| 51 | maxHttpBufferSize: MAX_HTTP_BUFFER_SIZE, |
| 52 | cookie: { |
| 53 | name: 'io', |
| 54 | path: '/', |
| 55 | httpOnly: true, |
| 56 | sameSite: 'none', |
| 57 | secure: isProd, |
| 58 | }, |
| 59 | }) |
| 60 | |
| 61 | if (env.REDIS_URL) { |
| 62 | logger.info('Configuring Socket.IO Redis adapter...') |
| 63 | |
| 64 | const redisOptions = { |
| 65 | url: env.REDIS_URL, |
| 66 | socket: { |
| 67 | reconnectStrategy: (retries: number) => { |
| 68 | if (retries > 10) { |
| 69 | logger.error('Redis adapter reconnection failed after 10 attempts') |
| 70 | return new Error('Redis adapter reconnection failed') |
| 71 | } |
| 72 | const delay = Math.min(retries * 100, 3000) |
| 73 | logger.warn(`Redis adapter reconnecting in ${delay}ms (attempt ${retries})`) |
| 74 | return delay |
| 75 | }, |
| 76 | }, |
| 77 | } |
| 78 | |
| 79 | // Create separate clients for pub and sub (recommended for reliability) |
| 80 | adapterPubClient = createClient(redisOptions) |
| 81 | adapterSubClient = createClient(redisOptions) |
| 82 | |
| 83 | adapterPubClient.on('error', (err) => { |
| 84 | logger.error('Redis adapter pub client error:', err) |
| 85 | }) |
| 86 | |
| 87 | adapterSubClient.on('error', (err) => { |
| 88 | logger.error('Redis adapter sub client error:', err) |
| 89 | }) |
| 90 | |
| 91 | adapterPubClient.on('ready', () => { |
| 92 | logger.info('Redis adapter pub client ready') |
| 93 | }) |
| 94 | |