Ethers.JS V6 WebSocketProvider长时间运行断连的保活方案咨询
Ethers.js V6 WebSocketProvider 连接保活方案
Ethers.js V6的WebSocketProvider本身自带重连与保活机制,但你手动创建WebSocket实例的方式可能没触发内置逻辑,导致长时间连接后无法监听block事件。下面是两种可行的保活方案:
方案1:用Provider内置管理+配置优化
不要手动创建WebSocket实例,直接把URL传给Provider,让它内部管理连接,同时配置重连和保活参数:
import { ethers } from "ethers"; function main() { const provider = new ethers.WebSocketProvider(`${config.WEB_SOCKET_URL}${config.ALCHEMY_API_KEY}`, { // 重连配置:断开后自动重试 reconnect: { delay: 1000, // 首次重连延迟1秒 maxDelay: 10000,// 最大重连延迟10秒 retries: Infinity // 无限重试直到连接成功 }, // 主动保活:定期发送ping检测连接 keepalive: { interval: 30000,// 每30秒发一次ping timeout: 10000 // ping超时10秒判定连接失效 } }); // 监听连接状态 provider.on("connect", () => console.log("WebSocket 连接成功")); provider.on("disconnect", err => console.log("WebSocket 断开:", err)); // 正常监听block事件 provider.on("block", blockNum => console.log("新区块:", blockNum)); } main();
方案2:自定义Socket时手动加保活逻辑
如果必须自己创建WebSocket实例(比如需要自定义初始化操作),可以给Socket加ping定时器,同时配合Provider的重连配置:
import { ethers } from "ethers"; import w3cwebsocket from "websocket"; function CreateSocketConnection() { console.log("创建WebSocket连接..."); const socket = new w3cwebsocket.w3cwebsocket(`${config.WEB_SOCKET_URL}${config.ALCHEMY_API_KEY}`); let pingTimer; // 连接打开后启动ping定时器 socket.onopen = () => { console.log("Socket 已打开"); pingTimer = setInterval(() => { if (socket.readyState === w3cwebsocket.OPEN) { // 用eth_blockNumber作为ping请求(节点普遍支持) socket.send(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_blockNumber", params: [] })); } }, 30000); }; // 关闭或出错时清理定时器 socket.onclose = () => { console.log("Socket 已关闭"); clearInterval(pingTimer); }; socket.onerror = err => { console.log("Socket 出错:", err); clearInterval(pingTimer); }; return socket; } function main() { const provider = new ethers.WebSocketProvider(CreateSocketConnection, { reconnect: { delay: 1000, maxDelay: 10000, retries: Infinity } }); provider.on("connect", () => console.log("Provider 连接成功")); provider.on("disconnect", err => console.log("Provider 断开:", err)); provider.on("block", blockNum => console.log("新区块:", blockNum)); } main();
注意事项
- 优先用方案1,Provider内置的逻辑已经覆盖了大部分断线重连、保活场景,不用自己造轮子。
- 调整
keepalive.interval时,参考节点服务商的要求(比如Alchemy建议不要太频繁),避免被限流。 - 监听
disconnect事件可以在断开时临时暂停业务逻辑,等重连成功后再恢复。
内容的提问来源于stack exchange,提问作者Caleb Priede
相关产品推荐
相关产品推荐

