Esta guía explica la interfaz JSON-RPC WebSocket de Polkadot, cubriendo wss vs ws, el puerto predeterminado 9944, cómo WsProvider de @polkadot/api gestiona suscripciones y reconexión, y cómo asegurar WSS con nginx. Incluye un script de suscripción ejecutable y una lista de verificación para solucionar problemas comunes como timeouts y errores de 'fetch failed'.
Respuesta directa: Lo que necesitas saber sobre el RPC WebSocket de Polkadot
Los nodos de Polkadot exponen un endpoint JSON-RPC WebSocket (puerto predeterminado 9944) que permite a los clientes consultar datos de la cadena y, crucialmente, suscribirse a actualizaciones en tiempo real. La variante segura es wss:// (WebSocket Secure), que cifra el tráfico usando TLS. Para aplicaciones de producción, siempre debes usar endpoints wss://, como los proporcionados por la página de red de Polkadot de OnFinality. La librería @polkadot/api abstrae la conexión WebSocket a través de su WsProvider, manejando suscripciones y lógica de reconexión. Esta guía explica la mecánica, proporciona un ejemplo ejecutable y ofrece pasos para solucionar problemas comunes de conexión.
Si estás construyendo una dApp o un indexador, probablemente usarás @polkadot/api para suscribirte a nuevos bloques, cabezas finalizadas o cambios de almacenamiento. Entender cómo funciona la conexión WebSocket internamente te ayuda a diagnosticar problemas como timeouts o desconexiones inesperadas. Vamos a profundizar en la arquitectura.
Cómo funciona el RPC WebSocket de Polkadot: wss vs ws y puerto 9944
Polkadot, construido sobre Substrate, usa JSON-RPC sobre WebSocket para todas las interacciones en tiempo real. El puerto WebSocket predeterminado es 9944, mientras que el puerto RPC HTTP es 9933. El esquema ws:// no está cifrado, mientras que wss:// usa cifrado TLS. Para cualquier uso en producción, debes usar wss:// para prevenir escuchas y ataques de intermediario. La guía de WebSocket seguro para desarrolladores de Polkadot explica cómo configurar un proxy WebSocket seguro.
Cuando te conectas a un nodo de Polkadot a través de WebSocket, el cliente envía solicitudes JSON-RPC y suscripciones. Las suscripciones son solicitudes de larga duración donde el servidor envía notificaciones. Por ejemplo, chain_subscribeNewHeads envía una notificación cada vez que se importa un nuevo bloque. El protocolo WebSocket incluye un mecanismo de keepalive ping/pong para detectar conexiones muertas. Si un cliente no recibe un pong dentro de un cierto tiempo de espera, puede considerar la conexión muerta e intentar reconectarse.
- Puerto WebSocket predeterminado: 9944
- WebSocket seguro: wss:// (cifrado TLS)
- Suscripciones: chain_subscribeNewHeads, chain_subscribeFinalizedHeads, state_subscribeStorage
- Keepalive: tramas ping/pong para mantener la conexión
Cómo WsProvider de @polkadot/api gestiona conexiones y suscripciones
La librería @polkadot/api usa WsProvider para gestionar conexiones WebSocket. Maneja el protocolo WebSocket de bajo nivel, incluyendo lógica de reconexión y gestión de suscripciones. Cuando creas una instancia de API con un endpoint WSS, WsProvider establece la conexión y se reconecta automáticamente si la conexión se cae. Usa una estrategia de backoff exponencial, comenzando con un retraso corto y aumentándolo hasta un máximo, para evitar sobrecargar el servidor.
Las suscripciones se gestionan mediante un ID de suscripción. Cuando llamas a api.rpc.chain.subscribeNewHeads(), el proveedor envía una solicitud chain_subscribeNewHeads. El servidor responde con un ID de suscripción, y el proveedor mapea ese ID a un callback. Si la conexión se cae, el proveedor se reconecta y automáticamente se vuelve a suscribir a todas las suscripciones activas, usando los mismos IDs de suscripción. Esto asegura que tu aplicación continúe recibiendo actualizaciones sin intervención manual.
Sin embargo, hay problemas conocidos. Por ejemplo, un problema común es que los timeouts de WsProvider no se capturan en bloques try-catch, como se discute en Substrate Stack Exchange. Esto puede llevar a rechazos de promesas no manejados. Además, los errores de 'fetch failed' ocurren a menudo cuando la conexión WebSocket no se establece correctamente, debido a problemas de red o URLs de endpoint incorrectas.
Ejemplo ejecutable: Suscribirse a nuevas cabezas con @polkadot/api
A continuación se muestra un script completo y ejecutable que se conecta a un endpoint WSS de Polkadot, se suscribe a nuevos encabezados de bloque y registra el número y hash del bloque. También demuestra cómo manejar desconexiones y reconexiones. Para ejecutarlo, necesitas Node.js y el paquete @polkadot/api instalado (npm install @polkadot/api).
El script usa un endpoint WSS público de OnFinality (reemplázalo con tu propio endpoint si es necesario). Configura una suscripción y registra cada nueva cabeza. También escucha eventos de 'connected' y 'disconnected' para mostrar el comportamiento de reconexión.
// polkadot-subscribe.js
const { ApiPromise, WsProvider } = require('@polkadot/api');
const WS_URL = 'wss://polkadot.api.onfinality.io/public-ws';
async function main() {
const provider = new WsProvider(WS_URL);
const api = await ApiPromise.create({ provider });
// Log connection events
provider.on('connected', () => console.log('Connected to', WS_URL));
provider.on('disconnected', () => console.log('Disconnected from', WS_URL));
provider.on('error', (err) => console.error('Provider error:', err));
// Subscribe to new heads
const unsub = await api.rpc.chain.subscribeNewHeads((head) => {
console.log(`New block #${head.number} hash: ${head.hash}`);
});
// Keep the process alive
process.on('SIGINT', async () => {
await unsub();
await api.disconnect();
process.exit(0);
});
}
main().catch(console.error);Salida esperada y cómo verificar
Cuando ejecutes el script, deberías ver una salida similar a la siguiente (los números de bloque y hashes reales variarán):
Connected to wss://polkadot.api.onfinality.io/public-ws
New block #12345678 hash: 0x1234...abcd
New block #12345679 hash: 0x5678...ef01
...
Para verificar que la suscripción funciona, puedes comparar los números de bloque con el último bloque en un explorador de bloques como Polkadot Subscan. El número de bloque debería aumentar en 1 cada 6 segundos (el tiempo promedio de bloque en Polkadot). Si no ves nuevos bloques, revisa tu conexión de red y la URL del endpoint. Además, asegúrate de que tu firewall permita conexiones WebSocket en el puerto 443 (para wss://).
Fallos comunes y soluciones: Timeout de WsProvider y 'fetch failed'
Dos problemas comunes que enfrentan los desarrolladores son los timeouts de WsProvider y los errores de 'fetch failed'. Un timeout ocurre cuando la conexión WebSocket se establece pero el servidor no responde dentro de un cierto tiempo. Esto puede suceder si el nodo está sobrecargado o la red es lenta. El WsProvider tiene un timeout incorporado (60 segundos por defecto) para el establecimiento de la conexión. Si se excede el timeout, lanza un error que puede no ser capturado por un try-catch alrededor de la llamada ApiPromise.create(), como se señala en Substrate Stack Exchange. Para manejar esto, puedes escuchar el evento 'error' del proveedor.
Los errores de 'fetch failed' típicamente ocurren cuando el handshake WebSocket falla, a menudo debido a una URL incorrecta, un firewall que bloquea la conexión o un problema de DNS. Este error es lanzado por la API fetch subyacente utilizada por la implementación de WebSocket. Para solucionarlo, verifica la URL del endpoint, comprueba que el servidor sea alcanzable (por ejemplo, usando curl o un cliente WebSocket) y asegúrate de que tu red permita conexiones WebSocket salientes.
Para una inmersión más profunda sobre por qué se caen las conexiones RPC WebSocket y cómo solucionarlo, consulta nuestra guía sobre por qué se caen las conexiones RPC WebSocket.
- Verifica la URL del endpoint y la conectividad de red
- Escucha los eventos 'error' del proveedor para capturar timeouts
- Usa un proveedor WSS confiable como el Asistente RPC de OnFinality
- Implementa lógica de reconexión personalizada si es necesario
Asegurando WSS detrás de nginx con TLS
Si ejecutas tu propio nodo de Polkadot, deberías exponerlo a través de un endpoint WebSocket seguro. La guía de WebSocket seguro para desarrolladores de Polkadot recomienda usar nginx como proxy inverso con terminación TLS. Esto te permite mantener el puerto WebSocket nativo del nodo (9944) vinculado a localhost y exponer un endpoint wss:// en el puerto 443.
Aquí hay una configuración mínima de nginx que proxifica conexiones WebSocket a un nodo local de Polkadot. Necesitas tener un certificado TLS (por ejemplo, de Let's Encrypt) y configurar proxy_pass a http://127.0.0.1:9944 con los encabezados WebSocket apropiados.
server {
listen 443 ssl;
server_name rpc.example.com;
ssl_certificate /etc/letsencrypt/live/rpc.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rpc.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:9944;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}Compensaciones y limitaciones del RPC WebSocket
Aunque el RPC WebSocket es potente, tiene limitaciones. Las suscripciones pueden consumir recursos significativos en el nodo, especialmente si muchos clientes se suscriben a cambios de almacenamiento. Los endpoints públicos a menudo imponen límites de tasa para proteger el nodo. Para aplicaciones de alto rendimiento, considera usar un endpoint dedicado o un servicio como el servicio API de OnFinality que ofrece infraestructura escalable.
Otra limitación es que las conexiones WebSocket son stateful, lo que puede ser problemático en entornos con balanceo de carga. Si un cliente se conecta a un servidor y luego el balanceador de carga enruta solicitudes posteriores a otro, la suscripción puede romperse. Las soluciones incluyen sesiones persistentes o usar un proveedor RPC centralizado que maneje esto de manera transparente.
Finalmente, la lógica de reconexión puede llevar a notificaciones duplicadas si el cliente se reconecta y se vuelve a suscribir. La librería @polkadot/api maneja esto usando IDs de suscripción, pero debes ser consciente de posibles eventos duplicados en la lógica de tu aplicación.
Próximos pasos y recursos adicionales
Ahora que entiendes el RPC WebSocket de Polkadot, puedes construir aplicaciones en tiempo real con confianza. Para comenzar, explora el centro de aprendizaje de OnFinality para más guías, o consulta nuestra página de red de Polkadot para endpoints disponibles. Si necesitas un servicio RPC confiable, considera nuestros precios y servicio API.
Para una lista completa de endpoints RPC de Polkadot, usa nuestro Asistente RPC. Y si encuentras problemas de conexión, consulta nuestra guía sobre por qué se caen las conexiones RPC WebSocket. ¡Feliz codificación!