Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
网络与协议指南12 分钟阅读

Monad WebSocket RPC:WSS 端点、eth_subscribe 与可靠的实时流

了解如何连接 Monad 的 WebSocket RPC,使用 eth_subscribe 获取实时数据,并通过重连和重新订阅逻辑构建健壮的订阅。

TL;DR

本指南介绍如何使用 Monad 的 WebSocket RPC 进行实时数据流传输。涵盖 WSS 端点、eth_subscribe 订阅方法、通知负载,并提供一个带有重连逻辑的可运行 Node.js 示例。还包括常见问题(如连接断开和高容量订阅)的故障排除提示。

直接回答:如何通过 WebSocket 从 Monad 获取实时数据

要从 Monad 获取实时数据,您需要连接到 WebSocket RPC 端点(wss://),并使用标准的以太坊 JSON-RPC eth_subscribe 方法订阅新区块、日志和待处理交易等事件。Monad 是一个兼容 EVM 的 L1,具有并行执行和亚秒级出块时间,因此其 WebSocket 接口遵循以太坊规范,但事件频率更高。本指南将引导您了解端点表面、订阅方法、通知格式,以及如何构建一个能够处理重连和重复通知的弹性客户端。

Monad 的官方文档提供了专门的 执行事件和 WebSocket 设置 部分和 实时数据源 页面,这些是本指南的主要参考。对于特定提供商的端点和限制,请务必查阅提供商的文档;我们将指出哪些行为由 Monad 记录,哪些因提供商而异。

  • Monad 支持标准的 eth_subscribe 方法:newHeadslogsnewPendingTransactionssyncing
  • 公共端点可能有连接限制和空闲超时;对于生产环境,请使用具有专用 WebSocket 支持的提供商。
  • Monad 的亚秒级出块时间意味着通知到达速度比以太坊更快,因此请设计您的客户端以处理高吞吐量。

Monad 的 WebSocket RPC 端点表面

Monad 在 wss:// URL 上公开 WebSocket RPC 端点,类似于以太坊。确切的端点取决于您的节点提供商。例如,公共端点可能是 wss://rpc.monad.xyz(请查看 Monad 文档以获取当前公共端点),而 Chainstack、QuickNode 或 Dwellir 等提供商提供自己的 WSS URL。始终使用 wss:// 方案进行加密连接;公共端点很少支持纯 ws://

Monad 的文档列出了支持的 JSON-RPC 方法,并指出了与以太坊的差异,例如区块标签和限制。对于 WebSocket,关键方法是 eth_subscribeeth_unsubscribe。订阅类型与以太坊相同:newHeadslogsnewPendingTransactionssyncing。Monad 还提供了一个自定义的 executionEvents 订阅,用于实时状态跟踪,如 执行事件和 WebSocket 设置 页面所述。

选择端点时,请考虑公共端点通常有速率限制,并可能断开空闲连接。对于生产环境,请使用提供专用 WebSocket 连接且限制更高的提供商。OnFinality 的 API 服务RPC 定价 页面提供了托管端点的详细信息。

  • 始终使用 wss:// 进行安全的 WebSocket 连接。
  • 查看提供商的文档以获取确切的 WSS URL 和任何连接限制。
  • Monad 的公共端点可能适合测试,但不适合高容量的生产使用。

理解 eth_subscribe 和通知负载

eth_subscribe 方法发送订阅请求并接收订阅 ID。然后,通知作为 JSON-RPC 响应推送,方法为 eth_subscriptionnewHeads 的负载包括区块头对象,其中包含 numberhashparentHashtimestamptransactionsRoot 等字段。对于 logs,负载包括日志对象,包含 addresstopicsdatablockNumbertransactionHashlogIndex

Monad 的亚秒级出块时间意味着 newHeads 通知比以太坊(约 12 秒出块)频繁得多。这对于处理每个区块的客户端来说可能是一个挑战,因此请考虑过滤或批处理。对于 logs,您可以指定 addresstopics 过滤器以减少通知量。

以下是 newHeads 通知负载的示例:

{
  "jsonrpc": "2.0",
  "method": "eth_subscription",
  "params": {
    "subscription": "0x1234567890abcdef",
    "result": {
      "number": "0x1b4",
      "hash": "0x...",
      "parentHash": "0x...",
      "timestamp": "0x...",
      "transactionsRoot": "0x..."
    }
  }
}

对于 logs,负载包括日志条目。您可以订阅特定合约地址和主题的日志以过滤相关事件。

  • newHeads 为每个新区块发送区块头。
  • logs 发送与过滤条件匹配的日志。
  • newPendingTransactions 发送待处理交易的交易哈希。
  • syncing 发送同步状态更改。

可运行示例:使用 ethers.js 订阅和重连

下面是一个完整的、自包含的 Node.js 脚本,使用 ethers.js 连接到 Monad WebSocket 端点,订阅新区块和日志,并处理重连和重新订阅。该脚本使用一个简单的重连循环,在连接断开后重新订阅相同的过滤器。它还通过跟踪最后看到的区块号来演示幂等重复通知处理。

要运行此脚本,请安装 ethers.js(npm install ethers)并将 MONAD_WSS_URL 环境变量设置为您的端点。该脚本记录每个通知,并演示如何通过跟踪最后看到的区块号来处理重复通知。

预期输出:脚本将记录订阅 ID,然后打印新区块通知(包含区块号和哈希),以及到达的日志通知。重复通知(例如重连后)通过 lastBlockNumber 检查进行过滤。要测试,请运行脚本并观察控制台。您应该每隔几秒看到一个新的区块通知(Monad 的出块时间亚秒级,因此预计通知会很快)。如果连接断开,脚本会自动重连并重新订阅。

  • 该脚本使用 provider.send 直接调用 eth_subscribe,适用于 ethers.js v6。
  • 重连逻辑很简单:在 'disconnected' 事件后延迟重连并重新订阅。
  • 通过跟踪 newHeads 的最后区块号来处理重复通知。
const { WebSocketProvider } = require('ethers');

const WSS_URL = process.env.MONAD_WSS_URL || 'wss://rpc.monad.xyz';

async function main() {
  let provider;
  let lastBlockNumber = 0;

  async function connect() {
    console.log('Connecting to', WSS_URL);
    provider = new WebSocketProvider(WSS_URL);

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

    provider.on('disconnected', () => {
      console.log('Disconnected. Reconnecting in 5s...');
      setTimeout(connect, 5000);
    });

    // Subscribe to new heads
    const headSub = await provider.send('eth_subscribe', ['newHeads']);
    console.log('Subscribed to newHeads with id:', headSub);

    // Subscribe to logs (example: all logs, adjust filter as needed)
    const logSub = await provider.send('eth_subscribe', ['logs', {}]);
    console.log('Subscribed to logs with id:', logSub);

    // Handle notifications
    provider.on('message', (message) => {
      const parsed = JSON.parse(message);
      if (parsed.method === 'eth_subscription') {
        const { subscription, result } = parsed.params;
        if (subscription === headSub) {
          const blockNum = parseInt(result.number, 16);
          if (blockNum > lastBlockNumber) {
            lastBlockNumber = blockNum;
            console.log('New head:', result.number, result.hash);
          } else {
            console.log('Duplicate head notification ignored:', result.number);
          }
        } else if (subscription === logSub) {
          console.log('New log:', result.address, result.topics);
        }
      }
    });
  }

  await connect();
}

main().catch(console.error);

常见故障和故障排除清单

与 Monad 的 WebSocket 连接可能因多种原因失败。以下是常见问题及解决方法:

订阅过多:某些提供商限制每个连接的活动订阅数量。如果超过限制,您可能会收到错误。减少订阅数量或使用多个连接。

每 IP 连接限制:公共端点通常限制每个 IP 的连接数。如果达到限制,您将被断开。使用限制更高的提供商或轮换 IP。

区块头滞后:如果您的客户端处理通知缓慢,可能会落后于链头。由于 Monad 出块速度快,这种情况更可能发生。优化您的处理或使用更强大的机器。

空闲超时:许多提供商在一段时间后关闭空闲连接。定期发送 ping 或 keepalive 消息以保持连接。

重连风暴:如果端点暂时不可用,您的客户端可能过于激进地重连。使用带有抖动的指数退避。

重复通知:重连后,您可能会收到已处理区块的通知。使用幂等处理(例如,跟踪最后处理的区块)。

  • 查看提供商的文档以了解订阅和连接限制。
  • 实现心跳(例如,每 30 秒发送 ping)以防止空闲超时。
  • 对重连尝试使用指数退避。
  • 设计您的事件处理为幂等以处理重复。

Monad WebSocket RPC 的权衡和限制

Monad 的快速出块时间是一把双刃剑:它们提供低延迟数据,但也增加了通知量。这可能会给客户端和网络带来压力。请考虑以下权衡:

吞吐量与成本:高频率订阅消耗更多带宽,并可能在托管提供商处产生更高成本。使用过滤器减少数据量。

最终性与链头:Monad 使用 MonadBFT 共识,出块时间亚秒级,但最终性可能滞后于链头。如果您需要最终数据,请订阅 newHeads 并使用 finalized 等区块标签检查最终性。

并行执行:Monad 的并行执行意味着交易以不同于以太坊的方式包含在区块中。这不会直接影响 WebSocket 订阅,但可能影响您解释日志和交易收据的方式。

提供商特定限制:每个提供商都有自己的速率限制、连接限制和定价。请务必查看提供商的文档。OnFinality 的 Monad RPC 速率限制和 429 指南涵盖了常见的速率限制问题。

公共端点不适用于生产:公共端点通常有速率限制,并且可能不可靠。对于生产环境,请使用专用提供商或运行您自己的节点。

  • 使用日志过滤器减少通知量。
  • 对于关键应用,考虑订阅 finalized 区块。
  • 监控您的带宽并调整订阅频率。
  • 对于生产环境,请使用托管提供商,如 OnFinality 的 API 服务

后续步骤和进一步阅读

既然您已经了解了 Monad WebSocket RPC,您可以自信地构建实时应用程序。以下是一些后续步骤:

探索 Monad 官方文档中的 执行事件和 WebSocket 设置,了解 executionEvents 等高级订阅类型。

查看 OnFinality 的 Monad RPC 端点 以获取可用端点及其功能的列表。

了解 Monad RPC 超时和重试 以优雅地处理网络问题。

理解 Monad RPC 速率限制和 429 以避免达到限制。

查看 OnFinality Learn 中心 获取更多关于 Monad 和其他网络的指南。

如果您正在 Monad 上构建,请考虑使用 OnFinality 的 API 服务 以获得可靠且可扩展的 RPC 访问。

  • 首先使用公共端点测试您的 WebSocket 客户端,然后迁移到提供商。
  • 实现健壮的错误处理和重连逻辑。
  • 使用指标监控您的订阅健康状况。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始