Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Guías de redes y protocolos12 min de lectura

Suscripciones WebSocket de Sui RPC: Flujos de eventos y mejores prácticas

Aprenda a usar la interfaz de suscripción WebSocket de Sui para transmitir eventos, checkpoints y épocas en tiempo real. Incluye ejemplos ejecutables en TypeScript, formas esperadas de los payloads y mejores prácticas para reconexión y límites de tasa.

TL;DR

La interfaz de suscripción WebSocket de Sui permite a los clientes recibir actualizaciones en tiempo real de eventos, checkpoints y épocas. Esta guía explica el flujo de suscripción, proporciona ejemplos ejecutables en TypeScript y cubre las mejores prácticas para reconexión, límites de tasa y el uso de GraphQL como alternativa.

Respuesta directa: ¿Qué son las suscripciones WebSocket de Sui?

La interfaz de suscripción WebSocket de Sui le permite recibir actualizaciones en tiempo real de la red sin necesidad de hacer polling. Puede suscribirse a tres tipos principales de datos: eventos (por ejemplo, transferencias de monedas, acuñaciones de NFT), checkpoints (lotes de transacciones confirmadas) y cambios de época (reconfiguración de la red). La suscripción utiliza el protocolo estándar JSON-RPC 2.0 sobre WebSocket, y el SDK de TypeScript de Sui proporciona un envoltorio conveniente. Esta guía le explica los mecanismos, proporciona código ejecutable y comparte las mejores prácticas para uso en producción.

Si busca una respuesta rápida: conéctese a un endpoint WebSocket (por ejemplo, wss://rpc.testnet.sui.io), envíe una solicitud de suscripción con un método como suix_subscribeEvent y escuche las notificaciones. El servidor envía mensajes con un campo params.result que contiene los datos del evento. Debe manejar las reconexiones manualmente, ya que la suscripción no sobrevive a las caídas de red. Para un servicio RPC administrado que maneja estas complejidades, consulte nuestra página de red de Sui.

Entendiendo la arquitectura de suscripción de Sui

La suscripción WebSocket de Sui se basa en el protocolo JSON-RPC 2.0. El cliente envía una solicitud de subscribe con un nombre de método y parámetros. El servidor responde con un ID de suscripción. A partir de entonces, el servidor envía mensajes de notificación (solicitudes JSON-RPC sin id) que incluyen el ID de suscripción y los datos del evento. Para cancelar la suscripción, envía una solicitud de unsubscribe con el ID de suscripción.

Los métodos de suscripción se agrupan bajo el espacio de nombres suix_. Los métodos principales son: suix_subscribeEvent (para eventos), suix_subscribeCheckpoint (para checkpoints) y suix_subscribeEpoch (para cambios de época). Estos son experimentales en algunas versiones de Sui, lo que significa que la API puede cambiar. Siempre consulte la documentación de mejores prácticas de RPC de Sui para conocer el estado más reciente.

El endpoint WebSocket es típicamente el mismo host que el RPC HTTP pero con wss:// en lugar de https://. Por ejemplo, si su URL RPC es https://rpc.testnet.sui.io, la URL WebSocket es wss://rpc.testnet.sui.io. OnFinality proporciona soporte WebSocket para Sui; consulte nuestro Asistente RPC para obtener detalles de endpoints.

  • Flujo de suscripción: solicitud -> ID de suscripción -> notificaciones -> cancelar suscripción
  • Métodos: suix_subscribeEvent, suix_subscribeCheckpoint, suix_subscribeEpoch
  • Estado experimental: la API puede cambiar sin previo aviso

Requisitos previos y configuración

Para ejecutar los ejemplos, necesita Node.js (v16 o posterior) y npm. Instale el SDK de TypeScript de Sui y el paquete ws para ejemplos WebSocket sin procesar. Si prefiere un cliente sin procesar, puede usar cualquier biblioteca WebSocket. Los ejemplos a continuación usan el SDK oficial para mayor claridad.

También necesita un endpoint RPC de Sui. Puede usar un endpoint público como wss://rpc.testnet.sui.io o un endpoint dedicado de OnFinality. Para producción, considere un endpoint dedicado para evitar límites de tasa; consulte nuestros precios para conocer las opciones.

npm install @mysten/sui.js ws
# o si usa el SDK más reciente (a partir de 2026):
npm install @mysten/sui

Ejemplo ejecutable: Suscripción a eventos con el SDK de TypeScript de Sui

El siguiente ejemplo se conecta a la testnet de Sui, se suscribe a todos los eventos e imprime los primeros 5 eventos. Utiliza el JsonRpcProvider del SDK. Tenga en cuenta que el método subscribeEvent del SDK devuelve una promesa que se resuelve en una función de cancelación de suscripción.

La forma del payload del evento incluye id (ID del evento), type (cadena del tipo de evento), sender (dirección), timestampMs y parsedJson (los datos específicos del evento). Los campos exactos dependen del tipo de evento. Por ejemplo, un evento 0x2::coin::CoinBalanceChange tiene campos coinType, amount y owner.

import { JsonRpcProvider, testnetConnection } from '@mysten/sui.js';

const provider = new JsonRpcProvider(testnetConnection);

async function subscribeToEvents() {
  const unsubscribe = await provider.subscribeEvent({
    filter: { All: [] }, // suscribirse a todos los eventos
    onMessage: (event) => {
      console.log('Evento recibido:', JSON.stringify(event, null, 2));
    },
  });

  // Cancelar suscripción después de 10 segundos
  setTimeout(async () => {
    await unsubscribe();
    console.log('Suscripción cancelada');
    process.exit(0);
  }, 10000);
}

subscribeToEvents().catch(console.error);

Ejemplo ejecutable: Cliente WebSocket sin procesar para suscripciones a checkpoints

Si prefiere un cliente WebSocket sin procesar, puede usar el paquete ws. Este ejemplo se suscribe a notificaciones de checkpoints e imprime el número de secuencia del checkpoint. El formato de la solicitud sigue JSON-RPC 2.0: { "jsonrpc": "2.0", "id": 1, "method": "suix_subscribeCheckpoint", "params": [] }.

El servidor responderá con { "jsonrpc": "2.0", "id": 1, "result": "<subscription_id>" }. Luego, cada notificación se verá así: { "jsonrpc": "2.0", "method": "suix_subscribeCheckpoint", "params": { "subscription": "<subscription_id>", "result": { "sequenceNumber": "123", "timestampMs": "...", ... } } }.

const WebSocket = require('ws');

const ws = new WebSocket('wss://rpc.testnet.sui.io');

ws.on('open', () => {
  console.log('Conectado');
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'suix_subscribeCheckpoint',
    params: [],
  }));
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  if (msg.id === 1) {
    console.log('ID de suscripción:', msg.result);
  } else if (msg.method === 'suix_subscribeCheckpoint') {
    console.log('Checkpoint:', msg.params.result.sequenceNumber);
  }
});

ws.on('error', (err) => console.error('Error de WebSocket:', err));

// Cerrar después de 15 segundos
setTimeout(() => ws.close(), 15000);

Forma esperada del payload del evento y cómo verificarla

Cuando se suscribe a eventos, el params.result de la notificación es un objeto con la siguiente estructura (según el esquema RPC de Sui): { "id": { "txDigest": "...", "eventSeq": "..." }, "type": "0x2::coin::CoinBalanceChange", "sender": "0x...", "timestampMs": "...", "parsedJson": { ... } }. El parsedJson varía según el tipo de evento.

Para verificar que su suscripción funciona, puede desencadenar una transacción (por ejemplo, transferir SUI) y ver el evento correspondiente. Alternativamente, puede comparar la secuencia del evento con la secuencia del checkpoint. Para obtener una lista completa de tipos de eventos, consulte la documentación de Sui.

Si utiliza el servicio RPC de OnFinality, puede monitorear su uso y la salud de la conexión a través del panel de servicio de API.

Fallos comunes y soluciones: Reconexión y límites de tasa

Las conexiones WebSocket son inherentemente inestables. Las caídas de red, los reinicios del servidor o los tiempos de espera por inactividad pueden desconectarlo. Cuando la conexión se cae, su suscripción se pierde. Debe reconectarse y volver a suscribirse. El SDK de Sui no se reconecta automáticamente, por lo que debe implementar un bucle de reconexión con retroceso exponencial.

Otro problema común es alcanzar los límites de tasa. Los endpoints públicos a menudo limitan el número de suscripciones o mensajes por segundo. Si excede el límite, el servidor puede cerrar la conexión o devolver un error. Para evitar esto, use un endpoint dedicado o reduzca el número de suscripciones. OnFinality proporciona servicios RPC escalables; consulte nuestra guía de RPC de Sui para más detalles.

Para obtener una guía detallada sobre cómo manejar desconexiones de WebSocket, consulte nuestro artículo sobre soluciones para desconexiones de RPC WebSocket.

  • Implemente la reconexión con retroceso exponencial y vuelva a suscribirse a todas las suscripciones activas.
  • Monitoree la salud de la conexión con tramas ping/pong.
  • Use un endpoint dedicado para evitar límites de tasa.

Compensaciones y limitaciones: WebSocket vs. GraphQL vs. Polling

Las suscripciones WebSocket proporcionan actualizaciones push de baja latencia, pero requieren conexiones persistentes y lógica de reconexión manual. El polling es más simple pero introduce latencia y carga adicional. Sui también ofrece una API GraphQL que admite suscripciones (a través de WebSocket) y consultas. GraphQL es más flexible para consultas complejas pero tiene una curva de aprendizaje.

La interfaz de suscripción WebSocket es experimental en algunas versiones de Sui, por lo que puede cambiar. Para producción, considere usar suscripciones GraphQL si necesita estabilidad. Sin embargo, para el streaming de eventos simple, WebSocket es eficiente.

OnFinality admite tanto WebSocket como GraphQL para Sui; consulte nuestra página de red para conocer los endpoints disponibles.

Próximos pasos y lecturas adicionales

Ahora que comprende las suscripciones WebSocket de Sui, puede construir aplicaciones en tiempo real como monitores de transacciones, rastreadores de NFT o paneles de análisis. Comience con los ejemplos anteriores y adáptelos a su caso de uso.

Para temas más avanzados, explore la documentación de mejores prácticas de RPC de Sui y nuestro centro de aprendizaje. Si necesita un servicio RPC confiable, considere el servicio de API o los precios de OnFinality para endpoints dedicados.

Si encuentra problemas, nuestro Asistente RPC proporciona consejos para la resolución de problemas. Y no olvide consultar nuestras soluciones para desconexiones de WebSocket para un manejo robusto de la conexión.

Ciclo de vida de la suscripción y formato de los mensajes

Cuando establece una suscripción WebSocket con Sui, el cliente y el servidor participan en un intercambio de mensajes específico que es crucial entender para una implementación robusta. Después de enviar una solicitud de suscripción (por ejemplo, {"jsonrpc":"2.0","id":1,"method":"suix_subscribeEvent","params":[...]}), el servidor responde con un mensaje de confirmación que incluye un ID de suscripción. Este ID es único para esa suscripción y se utiliza en notificaciones posteriores y para cancelar la suscripción. El mensaje de confirmación tiene la forma {"jsonrpc":"2.0","id":1,"result":"subscriptionId"}. Una vez suscrito, el servidor envía notificaciones de eventos como mensajes separados, cada uno con la estructura {"jsonrpc":"2.0","method":"suix_subscribeEvent","params":{"subscription":"subscriptionId","result":{...}}}. El campo result contiene los datos reales del evento. Es importante tener en cuenta que el campo method en la notificación refleja el método de suscripción, no el método JSON-RPC utilizado para la solicitud. Esto permite al cliente enrutar las notificaciones al manejador correcto cuando hay múltiples suscripciones activas.

El manejo de errores en el ciclo de vida de la suscripción a menudo se pasa por alto. Si una suscripción falla (por ejemplo, debido a parámetros no válidos o problemas de permisos), el servidor envía una respuesta de error con el mismo id que la solicitud, siguiendo el formato de error estándar de JSON-RPC. Sin embargo, después de que se establece una suscripción, también pueden ocurrir errores de forma asíncrona. Por ejemplo, si el servidor encuentra un error interno al procesar eventos, puede enviar una notificación con un campo method establecido en suix_subscribeEvent y un campo error en lugar de result. Los clientes deben estar preparados para manejar tanto notificaciones de éxito como de error. Además, el servidor puede enviar una notificación con el nombre de método suix_unsubscribeEvent para indicar que una suscripción ha sido terminada (por ejemplo, debido a un tiempo de espera del lado del servidor). Manejar adecuadamente estos mensajes asegura que su cliente pueda reaccionar con elegancia a terminaciones inesperadas.

  • Siempre haga coincidir el id en la respuesta de confirmación con la solicitud para correlacionar las suscripciones.
  • Use el ID de suscripción de la confirmación para administrar el estado y enrutar las notificaciones entrantes.
  • Maneje tanto los campos result como error en las notificaciones; los errores pueden ocurrir después de que la suscripción esté activa.
  • Tenga en cuenta que el servidor puede enviar una notificación de terminación; implemente lógica para volver a suscribirse si es necesario.
// Ejemplo de manejo de confirmación de suscripción y notificación
ws.on('message', (data) => {
  const msg = JSON.parse(data);
  if (msg.id !== undefined) {
    // Esta es una respuesta a una solicitud (por ejemplo, confirmación de suscripción)
    if (msg.result) {
      console.log('Suscrito con ID:', msg.result);
      subscriptionId = msg.result;
    } else if (msg.error) {
      console.error('Error de suscripción:', msg.error);
    }
  } else if (msg.method) {
    // Esta es una notificación
    if (msg.params && msg.params.subscription === subscriptionId) {
      if (msg.params.result) {
        console.log('Evento recibido:', msg.params.result);
      } else if (msg.params.error) {
        console.error('Error de notificación:', msg.params.error);
      }
    }
  }
});

Escalado de suscripciones y manejo idempotente de eventos

A medida que su aplicación crece, es posible que necesite manejar un alto volumen de eventos de múltiples suscripciones. Un patrón común es multiplexar muchas suscripciones sobre una sola conexión WebSocket. Sin embargo, esto introduce complejidad en la gestión de múltiples IDs de suscripción y en asegurar que los eventos se procesen correctamente. Una mejor práctica clave es tratar el manejo de eventos como idempotente. Dado que los problemas de red pueden causar entregas duplicadas, su lógica de procesamiento de eventos debe ser capaz de manejar el mismo evento múltiples veces sin efectos adversos. Los eventos de Sui incluyen un campo digest (un hash codificado en base58) que identifica de manera única el evento. Al mantener un conjunto de digests procesados recientemente (por ejemplo, en un caché con TTL), puede deduplicar eventos y evitar el doble procesamiento.

Otra consideración de escalado es el uso de múltiples conexiones WebSocket para distribuir la carga. Los proveedores de RPC de Sui a menudo imponen límites por conexión en el número de suscripciones o en la tasa de notificaciones. Al dividir las suscripciones entre múltiples conexiones (por ejemplo, según el tipo de evento o el rango de checkpoints), puede aumentar el rendimiento. Sin embargo, esto requiere una coordinación cuidadosa para asegurar que los eventos no se pierdan o se procesen fuera de orden. Para suscripciones de checkpoints, puede usar el parámetro startCheckpoint para reanudar desde un checkpoint específico, pero debe rastrear el último checkpoint procesado por conexión. Además, considere usar una cola de mensajes o un marco de procesamiento de flujos (como Apache Kafka o Redis Streams) para almacenar en búfer los eventos y desacoplar la ingesta del procesamiento. Esto le permite escalar el procesamiento horizontalmente sin perder eventos.

  • Use el digest del evento para deduplicar eventos; almacene los digests procesados en un caché con TTL.
  • Diseñe los manejadores de eventos para que sean idempotentes: procesar el mismo evento dos veces no debería tener efectos secundarios.
  • Considere dividir las suscripciones entre múltiples conexiones WebSocket para evitar los límites por conexión.
  • Rastree el último checkpoint procesado por conexión para permitir la reanudación después de desconexiones.
  • Integre una cola de mensajes para almacenar en búfer los eventos y desacoplar la ingesta del procesamiento para escalabilidad.
// Ejemplo de deduplicación usando un Set con TTL
const processedDigests = new Map(); // digest -> timestamp
const TTL_MS = 60000; // 1 minuto

function handleEvent(event) {
  const digest = event.digest;
  const now = Date.now();
  // Limpiar entradas antiguas
  for (const [key, ts] of processedDigests) {
    if (now - ts > TTL_MS) processedDigests.delete(key);
  }
  if (processedDigests.has(digest)) {
    console.log('Evento duplicado ignorado:', digest);
    return;
  }
  processedDigests.set(digest, now);
  // Procesar evento...
}

Ejemplo de cliente WebSocket sin procesar para suscripciones

Si bien el SDK de TypeScript de Sui proporciona un envoltorio conveniente, comprender el protocolo WebSocket sin procesar es esencial para depurar y para lenguajes sin soporte de SDK. A continuación se muestra un ejemplo completo usando la biblioteca ws de Node.js para suscribirse a eventos de Sui y recibir notificaciones. Este ejemplo demuestra el ciclo de vida completo: conexión, suscripción, manejo de notificaciones y cancelación de suscripción. También incluye manejo de errores y una estrategia simple de reconexión.

El ejemplo se suscribe a todos los eventos (usando un filtro vacío) y registra el tipo de evento y el digest. En la práctica, filtraría los eventos para reducir el ruido y el ancho de banda. El código también muestra cómo enviar una solicitud de cancelación de suscripción y cerrar la conexión correctamente. Tenga en cuenta que la URL WebSocket es el endpoint RPC estándar de Sui; puede reemplazarla con el endpoint de su proveedor. Para producción, considere usar una biblioteca como reconnecting-websocket para manejar las reconexiones automáticamente, pero este ejemplo proporciona una implementación manual para mayor claridad.

  • El ejemplo usa la biblioteca ws; instálela con npm install ws.
  • La solicitud de suscripción usa suix_subscribeEvent con un filtro vacío para recibir todos los eventos.
  • El campo id en la solicitud se usa para hacer coincidir la respuesta de confirmación.
  • Las notificaciones se identifican por el campo method y contienen el ID de suscripción.
  • Para cancelar la suscripción, envíe suix_unsubscribeEvent con el ID de suscripción.
const WebSocket = require('ws');

const ws = new WebSocket('wss://fullnode.mainnet.sui.io:443');
let subscriptionId = null;
let requestId = 1;

ws.on('open', () => {
  console.log('Conectado');
  // Suscribirse a todos los eventos
  const subscribeMsg = {
    jsonrpc: '2.0',
    id: requestId++,
    method: 'suix_subscribeEvent',
    params: [
      {
        filter: {} // Filtro vacío significa todos los eventos
      }
    ]
  };
  ws.send(JSON.stringify(subscribeMsg));
});

ws.on('message', (data) => {
  const msg = JSON.parse(data);
  if (msg.id !== undefined) {
    // Respuesta a nuestra solicitud
    if (msg.result) {
      subscriptionId = msg.result;
      console.log('Suscrito con ID:', subscriptionId);
    } else if (msg.error) {
      console.error('Error de suscripción:', msg.error);
    }
  } else if (msg.method === 'suix_subscribeEvent') {
    // Notificación
    const { subscription, result } = msg.params;
    if (subscription === subscriptionId) {
      console.log('Evento recibido:', result.type, result.digest);
    }
  }
});

ws.on('error', (err) => {
  console.error('Error de WebSocket:', err);
});

ws.on('close', () => {
  console.log('Conexión cerrada');
  // Lógica de reconexión aquí
});

// Para cancelar la suscripción más tarde:
function unsubscribe() {
  if (subscriptionId) {
    const unsubMsg = {
      jsonrpc: '2.0',
      id: requestId++,
      method: 'suix_unsubscribeEvent',
      params: [subscriptionId]
    };
    ws.send(JSON.stringify(unsubMsg));
  }
}

Limitaciones conocidas y supuestos

La API de suscripción WebSocket de Sui aún está evolucionando, y hay varias limitaciones y supuestos que debe tener en cuenta al construir aplicaciones. Primero, los métodos de suscripción (por ejemplo, suix_subscribeEvent, suix_subscribeCheckpoint) no forman parte de la API JSON-RPC estable y pueden cambiar sin previo aviso. La documentación de mejores prácticas de RPC de Sui señala explícitamente que las suscripciones son experimentales y están sujetas a cambios. Por lo tanto, debe fijar la versión de su SDK y monitorear las notas de lanzamiento de Sui para actualizaciones.

Segundo, los proveedores pueden imponer sus propios límites en las conexiones WebSocket, como el número máximo de suscripciones por conexión, límites de tasa de mensajes o duración de la conexión. Por ejemplo, un proveedor podría limitarlo a 100 suscripciones por conexión o desconectar conexiones inactivas después de 5 minutos. Estos límites no están estandarizados y pueden variar. Siempre consulte la documentación de su proveedor e implemente lógica de reconexión que respete estas restricciones. Tercero, la entrega de eventos no está garantizada como exactamente una vez; pueden ocurrir duplicados, y los eventos pueden perderse si la conexión se cae. Debe diseñar su sistema para tolerar la entrega al menos una vez y usar suscripciones de checkpoints para una reproducción confiable. Finalmente, la API de suscripción actualmente no admite el filtrado por digest de transacción o dirección de remitente directamente; debe filtrar los eventos del lado del cliente si es necesario. Esto puede llevar a un alto uso de ancho de banda si se suscribe a todos los eventos, así que use filtros con prudencia.

  • Las API de suscripción son experimentales y pueden cambiar; fije las versiones del SDK y monitoree las actualizaciones.
  • Los límites específicos del proveedor en conexiones, suscripciones y tasas son comunes; consulte la documentación.
  • La entrega de eventos es al menos una vez; los duplicados son posibles y pueden ocurrir eventos perdidos en desconexiones.
  • Use suscripciones de checkpoints para una reproducción confiable y para evitar perder eventos.
  • El filtrado del lado del cliente puede ser necesario para una selección de eventos detallada.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar