> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# LaserStream WebSocket: Transmissão de Dados Solana em Tempo Real

> Transmita dados da blockchain Solana em tempo real através de WebSockets com o LaserStream WebSocket — assinaturas padrão Solana mais extensões Helius, como transactionSubscribe, até 200 ms mais rápido que WebSockets baseados em RPC do Agave.

## O que é o LaserStream WebSocket?

LaserStream WebSocket é a variante do protocolo WebSocket do [LaserStream](/docs/pt-BR/laserstream). Oferece os métodos padrão Solana JSON-RPC de assinatura (`accountSubscribe`, `programSubscribe`, `logsSubscribe`, `signatureSubscribe`, `slotSubscribe`, …) juntamente com extensões específicas da Helius, como [`transactionSubscribe`](/docs/pt-BR/rpc/websocket/transaction-subscribe) para filtragem avançada — tudo no mesmo ponto de extremidade unificado `wss://mainnet.helius-rpc.com` e no mesmo backend do LaserStream como o [produto gRPC](/docs/pt-BR/laserstream).

WebSockets oferecem uma conexão persistente e em tempo real: em vez de consultar repetidamente "algo mudou?", a blockchain notifica você no momento em que algo acontece.

<CardGroup cols={2}>
  <Card title="Atualizações em Tempo Real" icon="bolt">
    Seja notificado instantaneamente quando contas Solana mudam, transações ocorrem ou novos blocos são produzidos
  </Card>

  <Card title="Uso Eficiente de Recursos" icon="leaf">
    Uma conexão persistente em vez de várias requisições HTTP
  </Card>

  <Card title="Baixa Latência" icon="clock">
    Até 200 ms mais rápido que WebSockets padrão baseados em RPC do Agave, servido por LaserStream
  </Card>

  <Card title="Extensões Helius" icon="filter">
    `transactionSubscribe` e um `accountSubscribe` aprimorado para filtragem avançada, além dos métodos Solana padrão
  </Card>
</CardGroup>

## Pontos de Extremidade

WebSockets — tanto os métodos padrão Solana quanto as extensões específicas da Helius — são fornecidos a partir de um único ponto de extremidade unificado por rede:

**Mainnet:** `wss://mainnet.helius-rpc.com/?api-key=<API_KEY>`
**Devnet:** `wss://devnet.helius-rpc.com/?api-key=<API_KEY>`

### Gatekeeper (Beta)

Para testar nossa oferta de WebSocket mais rápida, experimente o novo ponto de extremidade Gatekeeper (Beta):

`wss://beta.helius-rpc.com/?api-key=<API_KEY>`

## Preços e Medição

O uso do WebSocket é medido em **2 créditos por 0,1 MB** de dados transmitidos sem compressão. Abrir uma conexão custa **1 crédito**.

Para cargas de trabalho de alto volume em planos profissionais, [**Complementos de Dados**](/docs/pt-BR/billing/plans#data-add-ons) fornecem franquias de dados mensais (5TB–100TB) a custos previsíveis. Complementos de dados podem ser aplicados ao LaserStream e WebSockets.

<Note>
  Os métodos específicos da Helius `transactionSubscribe` e `accountSubscribe` (com filtros Helius) requerem um [plano](/docs/pt-BR/billing/plans) **Developer**, **Business** ou **Professional**. Métodos padrão Solana como `programSubscribe`, `logsSubscribe` e `signatureSubscribe` estão disponíveis em todos os planos.
</Note>

## Conceitos Fundamentais

### Tipos de Assinatura

<AccordionGroup>
  <Accordion title="Assinaturas de Conta" icon="user">
    Monitore mudanças em contas específicas, como saldos de carteiras, contas de token ou dados de programas.

    **Casos de uso:**

    * Rastreamento de saldo de carteira
    * Monitoramento de conta de token
    * Alterações no estado de contratos inteligentes
    * Atualizações de propriedade de NFT
  </Accordion>

  <Accordion title="Assinaturas de Programa" icon="code">
    Veja todas as contas pertencentes a um programa específico para quaisquer alterações.

    **Casos de uso:**

    * Monitoramento de negociações DEX
    * Rastreamento de protocolos DeFi
    * Atividade em mercados NFT
    * Alterações de ativos em jogos
  </Accordion>

  <Accordion title="Assinaturas de Transação" icon="receipt">
    Seja notificado quando transações específicas são confirmadas ou quando transações mencionam certas contas.

    **Casos de uso:**

    * Confirmações de pagamento
    * Rastreamento de status de transações
    * Aprovações de multiassinaturas
    * Monitoramento de execução de contrato
  </Accordion>

  <Accordion title="Assinaturas de Slot" icon="clock">
    Monitore a progressão e finalização da blockchain no nível de slot.

    **Casos de uso:**

    * Aplicações de exploradores de bloco
    * Monitoramento de saúde da rede
    * Rastreamento de consenso
    * Análises de desempenho
  </Accordion>
</AccordionGroup>

### Níveis de Comprometimento

Compreender os níveis de comprometimento é crucial para aplicações fiáveis:

<Tabs>
  <Tab title="Processado">
    **Mais Rápido** - Transação processada por um validador, mas não confirmada

    * Latência: \~400ms
    * Risco: Pode ser descartada ou reordenada
    * Uso: Atualizações de interface em tempo real (com cautela)
  </Tab>

  <Tab title="Confirmado">
    **Equilibrado** - Maioria do cluster votou no slot

    * Latência: \~2-3 segundos
    * Risco: Baixa chance de ser descartada
    * Uso: A maioria das aplicações
  </Tab>

  <Tab title="Finalizado">
    **Mais Seguro** - Supermaioria do cluster votou no slot

    * Latência: \~15-30 segundos
    * Risco: Extremamente improvável de ser descartada
    * Uso: Aplicações financeiras, transações de alto valor
  </Tab>
</Tabs>

<Info>
  **Quer saber mais sobre os níveis de comprometimento?** Leia nosso blog: [Compreendendo os Níveis de Comprometimento da Solana](https://www.helius.dev/blog/solana-commitment-levels)
</Info>

## Métodos WebSocket Disponíveis

A Helius suporta o conjunto completo de métodos de assinatura Solana WebSocket, além de extensões específicas da Helius. Todos os métodos compartilham o mesmo ponto de extremidade `wss://mainnet.helius-rpc.com`.

### Extensões Helius

Dois métodos oferecem filtragem mais rica que o padrão Solana:

* [`transactionSubscribe`](/docs/pt-BR/rpc/websocket/transaction-subscribe) — assine transações que correspondem a listas de contas incluídas/excluídas/necessárias, bandeiras de voto/erro, e uma assinatura específica
* [`accountSubscribe`](/docs/pt-BR/rpc/websocket/account-subscribe) — Helius adiciona filtros avançados sobre o formato padrão `accountSubscribe`

### Métodos padrão Solana

`accountSubscribe`, `blockSubscribe`, `logsSubscribe`, `programSubscribe`, `rootSubscribe`, `signatureSubscribe`, `slotSubscribe`, `slotsUpdatesSubscribe`, `voteSubscribe` e seus pares `*Unsubscribe` correspondentes.

<Card title="Referência Completa da API" icon="book" href="/docs/pt-BR/api-reference/rpc/websocket-methods">
  **Explore todos os 18+ métodos WebSocket**. Cada método inclui parâmetros detalhados, formatos de resposta e exemplos.
</Card>

## Como Implementar Lógica de Reconexão

Conexões WebSocket podem ser desconectadas por vários motivos - problemas de rede, manutenção do servidor ou interrupções temporárias. Aplicações de produção **devem** implementar lógica de reconexão para garantir confiabilidade.

### Por Que as Desconexões Acontecem

<AccordionGroup>
  <Accordion title="Problemas de Rede">
    * Problemas de conectividade com a Internet
    * Trocas de WiFi em dispositivos móveis
    * Tempos mortos em firewalls corporativos
    * Mudanças de roteamento de ISP
  </Accordion>

  <Accordion title="Eventos do Lado do Servidor">
    * Janelas de manutenção planejadas
    * Reinícios de balanceadores de carga
    * Atualizações de nós RPC
    * Proteção temporária contra sobrecarga
  </Accordion>

  <Accordion title="Problemas do Lado do Cliente">
    * Aba do navegador em segundo plano
    * Suspensão de aplicativo móvel
    * Computador em modo de espera/hibernação
    * Falhas ou reinícios de processos
  </Accordion>
</AccordionGroup>

### Detectando Desconexões

<Tabs>
  <Tab title="JavaScript/Navegador">
    ```javascript [expandable] theme={"system"}
    class ConnectionMonitor {
      constructor(ws) {
        this.ws = ws;
        this.pingInterval = null;
        this.lastPong = Date.now();
        this.isConnected = false;
        
        this.setupEventListeners();
        this.startPingMonitoring();
      }
      
      setupEventListeners() {
        this.ws.onopen = () => {
          console.log('Connected');
          this.isConnected = true;
          this.lastPong = Date.now();
        };
        
        this.ws.onclose = (event) => {
          console.log('Disconnected:', event.code, event.reason);
          this.isConnected = false;
          this.stopPingMonitoring();
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket error:', error);
          this.isConnected = false;
        };
        
        // Listen for pong responses (server acknowledgment)
        this.ws.onmessage = (event) => {
          const data = JSON.parse(event.data);
          if (data.method === 'pong') {
            this.lastPong = Date.now();
          }
          // Handle other messages...
        };
      }
      
      startPingMonitoring() {
        this.pingInterval = setInterval(() => {
          if (this.isConnected) {
            // Send ping to check connection health
            this.ws.send(JSON.stringify({
              jsonrpc: '2.0',
              method: 'ping',
              id: Date.now()
            }));
            
            // Check if we received a pong recently
            const timeSinceLastPong = Date.now() - this.lastPong;
            if (timeSinceLastPong > 30000) { // 30 seconds timeout
              console.warn('No pong received, connection may be stale');
              this.ws.close();
            }
          }
        }, 10000); // Ping every 10 seconds
      }
      
      stopPingMonitoring() {
        if (this.pingInterval) {
          clearInterval(this.pingInterval);
          this.pingInterval = null;
        }
      }
    }
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript [expandable] theme={"system"}
    const WebSocket = require('ws');

    class NodeConnectionMonitor {
      constructor(url) {
        this.url = url;
        this.ws = null;
        this.pingInterval = null;
        this.isAlive = false;
      }
      
      connect() {
        this.ws = new WebSocket(this.url);
        
        this.ws.on('open', () => {
          console.log('Connected');
          this.isAlive = true;
          this.startHeartbeat();
        });
        
        this.ws.on('close', () => {
          console.log('Disconnected');
          this.isAlive = false;
          this.stopHeartbeat();
        });
        
        this.ws.on('error', (error) => {
          console.error('WebSocket error:', error);
          this.isAlive = false;
        });
        
        // Built-in ping/pong handling
        this.ws.on('pong', () => {
          this.isAlive = true;
        });
      }
      
      startHeartbeat() {
        this.pingInterval = setInterval(() => {
          if (!this.isAlive) {
            console.log('Connection lost, terminating');
            return this.ws.terminate();
          }
          
          this.isAlive = false;
          this.ws.ping();
        }, 30000); // Ping every 30 seconds
      }
      
      stopHeartbeat() {
        if (this.pingInterval) {
          clearInterval(this.pingInterval);
          this.pingInterval = null;
        }
      }
    }
    ```
  </Tab>
</Tabs>

### Estratégias de Reconexão

<Tabs>
  <Tab title="Backoff Exponencial">
    ```javascript [expandable] theme={"system"}
    class ExponentialBackoffReconnector {
      constructor(url, maxRetries = 10) {
        this.url = url;
        this.maxRetries = maxRetries;
        this.retryCount = 0;
        this.baseDelay = 1000; // Start with 1 second
        this.maxDelay = 30000; // Cap at 30 seconds
        this.ws = null;
        this.subscriptions = new Map();
        this.isReconnecting = false;
      }
      
      connect() {
        if (this.isReconnecting) return;
        
        try {
          this.ws = new WebSocket(this.url);
          this.setupEventHandlers();
        } catch (error) {
          console.error('Failed to create WebSocket:', error);
          this.scheduleReconnect();
        }
      }
      
      setupEventHandlers() {
        this.ws.onopen = () => {
          console.log('Connected successfully');
          this.retryCount = 0; // Reset retry count on successful connection
          this.isReconnecting = false;
          this.resubscribeAll(); // Restore subscriptions
        };
        
        this.ws.onclose = (event) => {
          console.log('Connection closed:', event.code);
          if (!this.isReconnecting) {
            this.scheduleReconnect();
          }
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket error:', error);
        };
      }
      
      scheduleReconnect() {
        if (this.retryCount >= this.maxRetries) {
          console.error('Max retry attempts reached. Giving up.');
          return;
        }
        
        this.isReconnecting = true;
        this.retryCount++;
        
        // Calculate delay with exponential backoff + jitter
        const delay = Math.min(
          this.baseDelay * Math.pow(2, this.retryCount - 1),
          this.maxDelay
        );
        
        // Add jitter to prevent thundering herd
        const jitteredDelay = delay + (Math.random() * 1000);
        
        console.log(`Reconnecting in ${jitteredDelay}ms (attempt ${this.retryCount}/${this.maxRetries})`);
        
        setTimeout(() => {
          this.connect();
        }, jitteredDelay);
      }
      
      subscribe(method, params, callback) {
        const id = this.generateId();
        this.subscriptions.set(id, { method, params, callback });
        
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
          this.sendSubscription(id, method, params);
        }
        
        return id;
      }
      
      resubscribeAll() {
        console.log(`Restoring ${this.subscriptions.size} subscriptions`);
        for (const [id, sub] of this.subscriptions) {
          this.sendSubscription(id, sub.method, sub.params);
        }
      }
      
      sendSubscription(id, method, params) {
        this.ws.send(JSON.stringify({
          jsonrpc: '2.0',
          id: id,
          method: method,
          params: params
        }));
      }
      
      generateId() {
        return Date.now() + Math.random();
      }
    }
    ```
  </Tab>

  <Tab title="Padrão Circuit Breaker">
    ```javascript [expandable] theme={"system"}
    class CircuitBreakerWebSocket {
      constructor(url, options = {}) {
        this.url = url;
        this.failureThreshold = options.failureThreshold || 5;
        this.recoveryTimeout = options.recoveryTimeout || 60000;
        this.checkInterval = options.checkInterval || 10000;
        
        this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
        this.failureCount = 0;
        this.lastFailureTime = null;
        this.ws = null;
        this.subscriptions = new Map();
      }
      
      connect() {
        if (this.state === 'OPEN') {
          if (Date.now() - this.lastFailureTime > this.recoveryTimeout) {
            console.log('Circuit breaker moving to HALF_OPEN state');
            this.state = 'HALF_OPEN';
          } else {
            console.log('Circuit breaker is OPEN, connection blocked');
            return false;
          }
        }
        
        try {
          this.ws = new WebSocket(this.url);
          this.setupEventHandlers();
          return true;
        } catch (error) {
          this.recordFailure();
          return false;
        }
      }
      
      setupEventHandlers() {
        this.ws.onopen = () => {
          console.log('Connected - Circuit breaker CLOSED');
          this.state = 'CLOSED';
          this.failureCount = 0;
          this.resubscribeAll();
        };
        
        this.ws.onclose = () => {
          this.recordFailure();
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket error:', error);
          this.recordFailure();
        };
      }
      
      recordFailure() {
        this.failureCount++;
        this.lastFailureTime = Date.now();
        
        console.log(`Failure recorded: ${this.failureCount}/${this.failureThreshold}`);
        
        if (this.failureCount >= this.failureThreshold) {
          console.log('Circuit breaker opened due to repeated failures');
          this.state = 'OPEN';
        }
      }
      
      startHealthCheck() {
        setInterval(() => {
          if (this.state === 'OPEN' || 
              (this.ws && this.ws.readyState !== WebSocket.OPEN)) {
            this.connect();
          }
        }, this.checkInterval);
      }
    }
    ```
  </Tab>
</Tabs>

### Testando a Lógica de Reconexão

<Tabs>
  <Tab title="Simulação de Rede">
    ```javascript [expandable] theme={"system"}
    // Test disconnection scenarios
    class NetworkSimulator {
      constructor(wsManager) {
        this.wsManager = wsManager;
      }
      
      // Simulate network outage
      simulateNetworkOutage(duration = 5000) {
        console.log('Simulating network outage...');
        
        // Force close the connection
        if (this.wsManager.ws) {
          this.wsManager.ws.close(1006, 'Network outage simulation');
        }
        
        // Block reconnection temporarily
        const originalConnect = this.wsManager.connect.bind(this.wsManager);
        this.wsManager.connect = () => {
          console.log('Connection blocked during outage simulation');
        };
        
        // Restore connection after duration
        setTimeout(() => {
          console.log('Network restored');
          this.wsManager.connect = originalConnect;
          this.wsManager.connect();
        }, duration);
      }
      
      // Simulate intermittent connectivity
      simulateIntermittentConnectivity() {
        setInterval(() => {
          if (Math.random() < 0.1) { // 10% chance every 10 seconds
            console.log('Simulating connection drop...');
            this.wsManager.ws?.close(1006, 'Intermittent connectivity');
          }
        }, 10000);
      }
    }

    // Usage
    const simulator = new NetworkSimulator(wsManager);
    simulator.simulateNetworkOutage(10000); // 10 second outage
    ```
  </Tab>

  <Tab title="Teste Automatizado">
    ```javascript [expandable] theme={"system"}
    // Jest test example
    describe('WebSocket Reconnection', () => {
      let wsManager;
      
      beforeEach(() => {
        wsManager = new ProductionWebSocketManager({
          endpoint: 'ws://localhost:8080',
          apiKey: 'test-key'
        });
      });
      
      test('should reconnect after connection loss', async () => {
        const reconnectPromise = new Promise((resolve) => {
          wsManager.on('connected', resolve);
        });
        
        await wsManager.connect();
        
        // Simulate connection loss
        wsManager.ws.close(1006, 'Test disconnection');
        
        // Wait for reconnection
        await reconnectPromise;
        
        expect(wsManager.connectionState).toBe('CONNECTED');
        expect(wsManager.metrics.reconnections).toBeGreaterThan(0);
      });
      
      test('should restore subscriptions after reconnection', async () => {
        await wsManager.connect();
        
        const messages = [];
        const subscriptionId = wsManager.subscribe(
          'accountSubscribe',
          ['test-account', {}],
          (data) => messages.push(data)
        );
        
        // Verify subscription exists
        expect(wsManager.subscriptions.has(subscriptionId)).toBe(true);
        
        // Simulate disconnection and reconnection
        wsManager.ws.close(1006, 'Test disconnection');
        
        await new Promise(resolve => wsManager.on('connected', resolve));
        
        // Verify subscription was restored
        const subscription = wsManager.subscriptions.get(subscriptionId);
        expect(subscription.pending).toBe(true); // Should be re-subscribing
      });
    });
    ```
  </Tab>
</Tabs>

<Warning>
  **Crítico para Produção**: Implementar lógica de reconexão adequada não é opcional para aplicações de produção. Conexões WebSocket irão se desconectar - planeje, teste e monitore isso em produção.
</Warning>

## Solução de Problemas

<AccordionGroup>
  <Accordion title="Falha na Conexão">
    **Sintomas**: WebSocket falha ao conectar inicialmente

    **Soluções**:

    * Verifique se sua chave API está correta e possui créditos suficientes
    * Verifique o formato da URL do ponto de extremidade: `wss://mainnet.helius-rpc.com?api-key=YOUR_KEY`
    * Certifique-se de que seu firewall permite conexões WebSocket na porta 443
    * Teste com um simples ping primeiro para verificar a conectividade básica
  </Accordion>

  <Accordion title="Desconexões Frequentes">
    **Sintomas**: Conexão cai a cada poucos minutos

    **Soluções**:

    * WebSockets têm um **timer de inatividade de 10 minutos**. Envie um ping pelo menos uma vez por minuto para manter a conexão ativa (veja os exemplos de reconexão acima e o [FAQ WebSocket](/docs/pt-BR/faqs/websockets#why-are-my-enhanced-websockets-connections-disconnecting))
    * Implemente ping/pong de coração adequado (mostrado nos exemplos de reconexão acima)
    * Verifique a estabilidade de sua rede e configurações de firewall corporativo
    * Monitore sua contagem de assinaturas - muitas podem causar instabilidades
    * Verifique se você está lidando com o ciclo de vida da conexão corretamente
  </Accordion>

  <Accordion title="Mensagens Perdidas">
    **Sintomas**: Não recebendo atualizações de assinatura esperadas

    **Soluções**:

    * Verifique se sua assinatura está confirmada (verifique a resposta)
    * Certifique-se de que a conta/programa que você está monitorando tenha atividade real
    * Monitore o estado de sua conexão - mensagens perdidas geralmente indicam desconexões
  </Accordion>

  <Accordion title="Alta Latência">
    **Sintomas**: Entrega lenta de mensagens, atrasos nas atualizações

    **Soluções**:

    * Use "confirmado" em vez de "finalizado" como comprometimento
    * Reduza o número de assinaturas ativas
    * Otimize sua lógica de processamento de mensagens
    * Considere usar múltiplas conexões para distribuir carga
    * Verifique a qualidade de sua conexão de rede
  </Accordion>

  <Accordion title="Vazamentos de Memória">
    **Sintomas**: Uso de memória da aplicação cresce com o tempo

    **Soluções**:

    * Implemente limpeza adequada de assinaturas
    * Remova ouvintes de eventos quando componentes são desmontados
    * Limpe logs de mensagens periodicamente
    * Monitore a contagem de assinaturas e imponha limites
    * Use referências fracas para funções de callback quando possível
  </Accordion>
</AccordionGroup>

## Migração do RPC Padrão

Se você está atualmente usando polling HTTP, veja como migrar para WebSockets:

```javascript [expandable] theme={"system"}
// Old approach - HTTP polling
class HTTPAccountMonitor {
  constructor(connection, accountAddress) {
    this.connection = connection;
    this.accountAddress = accountAddress;
    this.interval = null;
    this.lastKnownBalance = null;
  }

  start() {
    this.interval = setInterval(async () => {
      try {
        const accountInfo = await this.connection.getAccountInfo(
          new PublicKey(this.accountAddress)
        );
        
        const currentBalance = accountInfo?.lamports || 0;
        
        if (this.lastKnownBalance !== currentBalance) {
          console.log(`Balance changed: ${currentBalance}`);
          this.lastKnownBalance = currentBalance;
        }
      } catch (error) {
        console.error('Failed to fetch account info:', error);
      }
    }, 2000); // Poll every 2 seconds
  }

  stop() {
    if (this.interval) {
      clearInterval(this.interval);
      this.interval = null;
    }
  }
}

// New approach - WebSocket subscription
class WebSocketAccountMonitor {
  constructor(wsManager, accountAddress) {
    this.wsManager = wsManager;
    this.accountAddress = accountAddress;
    this.subscriptionId = null;
  }

  start() {
    this.subscriptionId = this.wsManager.subscribe(
      'accountSubscribe',
      [
        this.accountAddress,
        { encoding: 'jsonParsed', commitment: 'confirmed' }
      ],
      (data) => {
        const currentBalance = data.value.lamports;
        console.log(`Balance changed: ${currentBalance}`);
        
        // Handle the change immediately - no polling delay!
      }
    );
  }

  stop() {
    if (this.subscriptionId) {
      this.wsManager.unsubscribe(this.subscriptionId);
      this.subscriptionId = null;
    }
  }
}
```

## Capacidades Aprimoradas

Para apps que exigem recursos ainda mais avançados, considere usar [LaserStream gRPC](/docs/pt-BR/laserstream):

<CardGroup cols={2}>
  <Card title="Reprodução Histórica de 24 Horas" icon="clock-rotate-left">
    Recupere dados perdidos quando seu app estava offline
  </Card>

  <Card title="Agregação Multi-Node" icon="network-wired">
    Melhor confiabilidade via dados de múltiplos validadores
  </Card>

  <Card title="Maior Taxa de Transferência" icon="gauge-high">
    Lide com mais assinaturas e maiores taxas de mensagens
  </Card>

  <Card title="Recursos Empresariais" icon="building">
    Monitoramento avançado, análises, e pipelines de dados
  </Card>
</CardGroup>

## Comece Agora

Pronto para Começar?

Confira nosso [Guia Rápido WebSocket](/docs/pt-BR/rpc/websocket/quickstart) para exemplos práticos e uma implementação passo a passo.
