Esta guía explica la API WebSocket PubSub de Solana, cubriendo métodos de suscripción, ciclo de vida de la conexión y fallos comunes. Incluye un ejemplo ejecutable en Node.js usando @solana/web3.js y una lista de verificación para solución de problemas.
Respuesta Directa: ¿Qué es Solana RPC WebSocket?
La API WebSocket RPC de Solana (también llamada PubSub) te permite recibir notificaciones en tiempo real sobre cambios de cuentas, actividad de programas y registros de transacciones a través de una conexión WebSocket persistente. A diferencia de consultar el endpoint HTTP JSON-RPC estándar, las suscripciones WebSocket envían datos a tu cliente tan pronto como están disponibles, reduciendo la latencia y la carga. El endpoint oficial es ws://<DIRECCIÓN>/ o wss://<DIRECCIÓN>/ (por ejemplo, ws://localhost:8899 para un validador local, o la URL wss de un proveedor RPC público). Esta guía cubre los tres métodos de suscripción principales—accountSubscribe, programSubscribe y logsSubscribe—además de las suscripciones de slot y root, y explica el ciclo de vida completo de la conexión con un ejemplo ejecutable en Node.js.
La API WebSocket de Solana es JSON-RPC 2.0 sobre WebSocket, con un patrón de solicitud/respuesta para suscripciones y un formato de notificación para eventos entrantes. Es distinta del eth_subscribe estilo EVM porque el modelo de Solana está centrado en cuentas y utiliza la programación basada en el líder para el tiempo de las notificaciones. Comprender estas diferencias es clave para construir aplicaciones confiables en tiempo real.
- Familias de endpoints:
ws://localhost:8899para desarrollo local,wss://para proveedores RPC públicos (por ejemplo,wss://api.mainnet-beta.solana.com). - Tres métodos de suscripción principales:
accountSubscribe,programSubscribe,logsSubscribe. - Métodos adicionales:
slotSubscribe,rootSubscribeysignatureSubscribe(aunque las notificaciones de firma a menudo se manejan mediante polling). - Cancelar suscripción mediante
accountUnsubscribe,programUnsubscribe,logsUnsubscribe, etc.
Cómo Funciona Solana PubSub: Arquitectura y Flujo de Notificaciones
La API PubSub de Solana está construida sobre JSON-RPC 2.0. Para suscribirte, envías una solicitud con un nombre de método y parámetros, y el servidor responde con un ID de suscripción. A partir de entonces, el servidor envía mensajes de notificación (notificaciones JSON-RPC 2.0) al cliente cada vez que ocurre el evento suscrito. Cada notificación incluye el ID de suscripción y la carga útil de datos.
La cadencia de notificaciones está vinculada al programa de líderes de Solana. Para accountSubscribe y programSubscribe, las notificaciones se envían cuando los datos de la cuenta o del programa cambian, pero solo después de que un slot sea confirmado. Para logsSubscribe, las notificaciones se envían por cada mensaje de registro emitido por transacciones que tocan el programa o la cuenta suscrita. Esto significa que podrías ver ráfagas de notificaciones alrededor de los cambios de líder, y puede haber un ligero retraso en comparación con el procesamiento real de la transacción.
La documentación oficial de Solana (Métodos WebSocket RPC de Solana) especifica los formatos exactos de solicitud y notificación. Por ejemplo, una solicitud de suscripción se ve así: {"jsonrpc":"2.0","id":1,"method":"accountSubscribe","params":["PUBKEY",{"encoding":"base64","commitment":"confirmed"}]}. La respuesta es {"jsonrpc":"2.0","result":"SUBSCRIPTION_ID","id":1}. Las notificaciones llegan entonces como {"jsonrpc":"2.0","method":"accountNotification","params":{"result":{"context":{"slot":123},"value":{...}},"subscription":"SUBSCRIPTION_ID"}}.
- Formato de solicitud: solicitud JSON-RPC 2.0 con método, parámetros e id.
- Formato de respuesta: respuesta JSON-RPC 2.0 con resultado (ID de suscripción) e id.
- Formato de notificación: notificación JSON-RPC 2.0 con método (por ejemplo,
accountNotification) y parámetros que contienen ID de suscripción y resultado. - Niveles de compromiso:
processed,confirmed,finalizedafectan cuándo se envían las notificaciones.
Análisis Profundo de los Métodos de Suscripción
Los tres métodos de suscripción principales son accountSubscribe, programSubscribe y logsSubscribe. Cada uno tiene parámetros específicos y cargas útiles de notificación.
accountSubscribe monitorea los cambios de estado de una sola cuenta. Parámetros: clave pública de la cuenta (cadena base58) y objeto de configuración opcional con commitment y encoding. La carga útil de notificación incluye los datos de la cuenta, lamports, propietario, indicador de ejecutable, época de alquiler y contexto de slot.
programSubscribe monitorea todas las cuentas propiedad de un programa. Parámetros: clave pública del programa y configuración opcional con encoding y filters (por ejemplo, dataSize o memcmp). Las notificaciones son similares a las de cuenta pero para cualquier cuenta propiedad del programa.
logsSubscribe monitorea los registros de transacciones. Parámetros: un filtro (ya sea "all", {"mentions": [pubkey]} para menciones de cuenta o programa, o {"mentions": [pubkey], "commitment": "confirmed"}) y compromiso opcional. Las notificaciones incluyen la matriz de registros, firma y slot.
Además, slotSubscribe y rootSubscribe proporcionan actualizaciones de slot y root, útiles para rastrear el progreso de la cadena. signatureSubscribe también está disponible pero a menudo se usa menos porque requiere conocer la firma de antemano.
- accountSubscribe:
params: [pubkey, {encoding, commitment}] - programSubscribe:
params: [programId, {encoding, filters, commitment}] - logsSubscribe:
params: [filter, {commitment}]donde filter es"all"o{"mentions": [pubkey]} - slotSubscribe:
params: [] - rootSubscribe:
params: [] - Métodos de cancelación:
accountUnsubscribe,programUnsubscribe,logsUnsubscribe, etc.
Ejemplo Ejecutable en Node.js con @solana/web3.js
La forma más fácil de usar las suscripciones WebSocket de Solana es mediante la biblioteca @solana/web3.js, que envuelve la API WebSocket cruda. La clase Connection proporciona métodos como onAccountChange, onProgramAccountChange y onLogs que manejan la suscripción y el análisis de notificaciones automáticamente.
A continuación se muestra un ejemplo completo que se suscribe a cambios de cuenta para una dirección dada, cambios de cuentas de programa para un ID de programa y registros para un programa. También demuestra cómo manejar la reconexión y la limpieza. Para ejecutarlo, instala @solana/web3.js y ws (para WebSocket en Node.js).
Salida esperada: El script imprimirá los IDs de suscripción y luego registrará las notificaciones a medida que lleguen. Dado que los datos en tiempo real dependen de la actividad de la red, es posible que necesites activar algunas transacciones para ver notificaciones. El ejemplo incluye un tiempo de espera para salir después de 30 segundos.
- Usa
Connectioncon una URL WebSocket (por ejemplo,wss://api.mainnet-beta.solana.com). onAccountChangedevuelve un ID de suscripción (número).onProgramAccountChangeacepta un ID de programa y un filtro opcional.onLogsacepta un filtro (por ejemplo,'all'o{mentions: [programId]}).- Maneja siempre los eventos
errorycloseen el WebSocket para implementar la reconexión.
// Instalar: npm install @solana/web3.js ws
const { Connection, PublicKey } = require('@solana/web3.js');
// Reemplaza con tu endpoint (por ejemplo, wss://api.mainnet-beta.solana.com)
const wsUrl = 'wss://api.mainnet-beta.solana.com';
const connection = new Connection(wsUrl, 'confirmed');
// Ejemplo: suscribirse a cambios de cuenta para una cuenta de token conocida
const accountPubkey = new PublicKey('YOUR_ACCOUNT_PUBKEY');
const subId = connection.onAccountChange(accountPubkey, (accountInfo, context) => {
console.log('Cambio de cuenta en el slot', context.slot);
console.log('Lamports:', accountInfo.lamports);
console.log('Longitud de datos:', accountInfo.data.length);
}, 'confirmed');
// Suscribirse a cambios de cuentas de programa (por ejemplo, programa SPL Token)
const programId = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
const programSubId = connection.onProgramAccountChange(programId, (accountInfo, context) => {
console.log('Cambio de cuenta de programa en el slot', context.slot);
}, 'confirmed');
// Suscribirse a registros del mismo programa
const logsSubId = connection.onLogs(programId, (logs, context) => {
console.log('Registros en el slot', context.slot);
console.log('Firma:', logs.signature);
console.log('Registros:', logs.logs);
}, 'confirmed');
console.log('Suscrito con IDs:', subId, programSubId, logsSubId);
// Mantener el proceso vivo y manejar la limpieza
setTimeout(() => {
connection.removeAccountChangeListener(subId);
connection.removeProgramAccountChangeListener(programSubId);
connection.removeOnLogsListener(logsSubId);
console.log('Cancelada la suscripción y saliendo.');
process.exit(0);
}, 30000);
// Salida esperada (ejemplo):
// Suscrito con IDs: 1 2 3
// Cambio de cuenta en el slot 123456
// Lamports: 2039280
// Longitud de datos: 165
// ... (notificaciones a medida que ocurren)Ciclo de Vida de la Conexión: Keepalive, Reconexión y Re-suscripción
Una conexión WebSocket al endpoint PubSub de Solana no es permanente. Puede caerse debido a problemas de red, reinicios del servidor o tiempos de espera por inactividad. Para construir un cliente robusto, debes manejar el ciclo de vida de la conexión: conectar, mantener viva, detectar cierre y re-suscribir.
Keepalive: La mayoría de los servidores WebSocket envían tramas de ping periódicamente. En Node.js, la biblioteca ws responde automáticamente a los pings, pero también puedes enviar pings a nivel de aplicación. La documentación oficial de Solana no especifica un intervalo de keepalive, pero es común enviar un ping cada 30 segundos para evitar tiempos de espera por inactividad. Si usas @solana/web3.js, la biblioteca maneja los pings internamente, pero aún debes escuchar los eventos close.
Reconexión: Cuando la conexión se cierra, necesitas reconectar y restablecer todas las suscripciones. La clase Connection de @solana/web3.js no se re-suscribe automáticamente; debes implementarlo. Un patrón común es envolver la configuración de suscripciones en una función y llamarla al reconectar. Puedes usar una biblioteca como reconnecting-websocket o escribir tu propia lógica.
Re-suscripción: Después de reconectar, debes llamar a los métodos de suscripción nuevamente. Realiza un seguimiento de tus IDs de suscripción y los parámetros utilizados, para poder re-suscribirte con los mismos filtros. Ten en cuenta que los IDs de suscripción pueden cambiar después de la reconexión.
Para una inmersión más profunda en soluciones genéricas de desconexión WebSocket, consulta nuestra guía genérica de desconexiones WebSocket RPC.
- Escucha los eventos
open,message,erroryclose. - Implementa retroceso exponencial para los intentos de reconexión (por ejemplo, 1s, 2s, 4s, máx. 30s).
- Al reconectar, re-suscríbete a todas las suscripciones activas.
- Usa un heartbeat (ping/pong) para detectar conexiones muertas.
- Considera usar una biblioteca como
reconnecting-websocketpara reconexión automática.
// Ejemplo de lógica de reconexión usando ws y @solana/web3.js
const WebSocket = require('ws');
const { Connection } = require('@solana/web3.js');
let connection;
let subscriptions = [];
function setupSubscriptions() {
// Limpiar suscripciones antiguas
subscriptions.forEach(id => connection.removeAllListeners(id));
subscriptions = [];
// Re-suscribirse
const subId = connection.onAccountChange(accountPubkey, callback, 'confirmed');
subscriptions.push(subId);
// ... añadir otras suscripciones
}
function connect() {
connection = new Connection(wsUrl, 'confirmed');
connection._ws.on('close', () => {
console.log('Conexión cerrada. Reconectando en 5s...');
setTimeout(connect, 5000);
});
connection._ws.on('open', () => {
console.log('Conectado. Configurando suscripciones.');
setupSubscriptions();
});
}
connect();Fallos Comunes y Lista de Verificación para Solución de Problemas
Incluso con una implementación sólida, puedes encontrar problemas. Aquí hay fallos comunes y cómo solucionarlos.
Desconexión bajo carga: Las suscripciones de alto rendimiento pueden abrumar a tu cliente o al servidor. Si ves desconexiones frecuentes, reduce el número de suscripciones o usa filtros para limitar los datos. También asegúrate de que tu cliente procese los mensajes rápidamente; si tu callback es lento, puede bloquear el bucle de eventos y causar tiempos de espera.
Retraso en las notificaciones: Las notificaciones están vinculadas al programa de líderes y al nivel de compromiso. Si necesitas actualizaciones más rápidas, usa el compromiso processed, pero ten en cuenta que los datos pueden revertirse. Para datos finales, usa confirmed o finalized.
Uso incorrecto de filtros: Para programSubscribe, filtros como dataSize y memcmp deben tener el formato correcto. memcmp requiere offset y bytes (codificados en base58). Si no recibes notificaciones, verifica tu lógica de filtros.
Errores de conexión: Los errores comunes incluyen Unexpected server response: 403 (si el endpoint requiere una clave API) o WebSocket is closed before the connection is established. Asegúrate de que tu URL sea correcta y tengas acceso a la red.
ID de suscripción no encontrado: Si intentas cancelar la suscripción con un ID inválido, obtendrás un error. Realiza un seguimiento de los IDs y elimina los listeners correctamente.
- Verifica tu URL de endpoint: usa
wss://para conexiones seguras y asegúrate de que sea accesible. - Verifica el nivel de compromiso:
processedes el más rápido pero menos confiable;confirmedes un buen valor predeterminado. - Usa filtros para reducir el volumen de datos:
dataSizeymemcmppara suscripciones de programa. - Monitorea el estado de tu conexión WebSocket e implementa reconexión con retroceso.
- Prueba con un validador local (
solana-test-validator) para evitar límites de velocidad. - Si usas un proveedor RPC público, consulta su documentación sobre límites de velocidad y reglas específicas de WebSocket.
Compensaciones y Limitaciones
La API PubSub de Solana es poderosa pero tiene compensaciones. Las notificaciones no están garantizadas en orden o completas; puedes perder eventos si la conexión se cae. Además, la cadencia de notificaciones depende del programa de líderes, por lo que podrías ver ráfagas de actividad en lugar de un flujo constante.
Retención de endpoints: Los proveedores RPC públicos pueden tener diferentes políticas de retención para conexiones WebSocket. Algunos pueden desconectar conexiones inactivas después de un cierto período. Siempre implementa lógica de reconexión.
El tiempo de las notificaciones varía según el proveedor y la carga de la red. No confíes en tiempos exactos para aplicaciones críticas; usa niveles de compromiso para equilibrar velocidad y confiabilidad.
En comparación con eth_subscribe de EVM, el modelo de Solana está centrado en cuentas y requiere comprender el modelo de cuentas de Solana. Por ejemplo, programSubscribe es similar a eth_subscribe para eventos de contratos pero opera en cambios de estado de cuentas.
Para producción, considera usar un proveedor WebSocket dedicado con alta disponibilidad. El servicio API de OnFinality ofrece endpoints WebSocket confiables, y puedes comparar endpoints RPC de Solana en nuestro RPC Assistant.
- Las notificaciones no están garantizadas sin pérdidas; implementa tu propia reconciliación si es necesario.
- Los endpoints públicos pueden tener límites de velocidad; consulta la documentación de tu proveedor.
- Las conexiones WebSocket son stateful; la reconexión es obligatoria en producción.
- Usa el compromiso
finalizedpara datos irreversibles, pero espera mayor latencia. - Para casos de uso de alto rendimiento, considera usar un servicio de streaming dedicado como Helius LaserStream (tercero independiente).
Próximos Pasos y Lecturas Adicionales
Ahora que comprendes la API WebSocket de Solana, puedes construir aplicaciones en tiempo real como monitores de transacciones, rastreadores de cartera o bots de arbitraje. Comienza con la documentación oficial de Métodos WebSocket RPC de Solana para los formatos JSON exactos.
Si eres nuevo en el desarrollo de Solana, explora nuestra guía de red de Solana para una visión general. Para consideraciones de precios, consulta precios RPC. Si encuentras problemas de desconexión, consulta nuestra guía genérica de desconexiones WebSocket RPC.
Para una comprensión más amplia de los servicios RPC, visita el centro de aprendizaje de OnFinality para más tutoriales y guías.
- Documentación oficial de WebSocket de Solana: solana.com/docs/rpc/websocket
- Descripción general de RPC de Solana: docs.solana.com/api
- Endpoints RPC de Solana de OnFinality: RPC Assistant
- Explora nuestro servicio API para endpoints WebSocket gestionados.