You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 09:01:23