Skip to content

Sistema em Tempo Real

O ProCases utiliza WebSocket para comunicação em tempo real, permitindo atualizações instantâneas de saldo, drops ao vivo, batalhas e notificações.

Arquitetura

Componentes

Socket.io com Redis Adapter

O RedisIoAdapter (src/infrastructure/websocket/redis-io.adapter.ts) permite escalabilidade horizontal - múltiplas instâncias do backend podem compartilhar conexões WebSocket. Ele possui fallback graceful para o adapter in-memory single-node quando REDIS_HOST/REDIS_PASSWORD estão ausentes ou a conexão falha.

Status atual

O wiring do Redis Adapter está desativado em src/main.ts (não há app.useWebSocketAdapter(...)). Hoje o Socket.io roda in-memory / single-node. O fan-out de eventos de crash entre containers NÃO usa o redis-adapter do Socket.io: ele é feito por um relay dedicado (CrashWsRelayService, Redis Pub/Sub com prefixo de canal crash:ws:emit:). Para escalar o WebSocket horizontalmente basta reativar o adapter.

typescript
// redis-io.adapter.ts
import { IoAdapter } from '@nestjs/platform-socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { Redis } from 'ioredis';

export class RedisIoAdapter extends IoAdapter {
  private adapterConstructor: ReturnType<typeof createAdapter>;

  async connectToRedis(): Promise<void> {
    const pubClient = new Redis({
      host: process.env.REDIS_HOST,
      port: Number(process.env.REDIS_PORT),
    });
    
    const subClient = pubClient.duplicate();

    this.adapterConstructor = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: any): any {
    const server = super.createIOServer(port, {
      ...options,
      cors: {
        origin: process.env.FRONTEND_URL,
        credentials: true,
      },
    });
    
    server.adapter(this.adapterConstructor);
    return server;
  }
}

Seções

Fluxo de Conexão

Tipos de Conexão

Conexão Autenticada

Usuários logados recebem eventos personalizados:

  • Atualizações de saldo
  • Notificações privadas
  • Status de jogos em andamento
  • Convites para batalhas

Conexão Pública

Visitantes não autenticados recebem apenas eventos públicos:

  • Live drops
  • Novas batalhas
  • Resultados de sorteios
  • Estatísticas gerais

Escalabilidade

Sticky Sessions: O load balancer usa sticky sessions para manter conexões WebSocket na mesma instância.

Nota: Este é o desenho-alvo de escala horizontal. No estado atual (single-node, ver aviso acima) ele só entra em vigor quando o RedisIoAdapter é reativado no main.ts.

Configuração do Cliente

typescript
// Frontend - WebSocket Context
import { io, Socket } from 'socket.io-client';

const createSocket = (sessionId?: string): Socket => {
  return io(process.env.NEXT_PUBLIC_WS_URL, {
    auth: sessionId ? { sessionId } : undefined,
    withCredentials: true,
    transports: ['websocket', 'polling'],
    reconnection: true,
    reconnectionAttempts: 5,
    reconnectionDelay: 1000,
    reconnectionDelayMax: 5000,
  });
};

Métricas

O sistema coleta métricas de WebSocket via Prometheus:

MétricaDescrição
ws_connections_totalTotal de conexões ativas
ws_connections_authenticatedConexões autenticadas
ws_events_sent_totalEventos enviados
ws_events_received_totalEventos recebidos
ws_rooms_countNúmero de rooms ativos

Documentação Técnica - ProCases