跳转到主要内容

使用 WebSocket

Alchemy
websockets
查询
JavaScript
初级
埃兰·哈尔彭
2020年12月1日
8 分钟阅读

这是一篇关于使用 WebSocket 和 Alchemy 向以太坊区块链发起请求的入门指南。

 (opens in a new tab)WebSocket 与 HTTP 的对比

与 HTTP 不同,使用 WebSocket 时,你不需要在想要获取特定信息时不断发起请求。WebSocket 会为你维持一个网络连接(如果配置正确的话)并监听变化。

与任何网络连接一样,你不应假设 WebSocket 会永远保持打开状态而不中断,但手动正确处理掉线和重连可能会非常具有挑战性。WebSocket 的另一个缺点是,你无法在响应中获得 HTTP 状态码,只能获得错误消息。

Alchemy Web3 (opens in a new tab) 自动添加了对 WebSocket 故障和重试的处理,无需任何配置。

试一试

测试 WebSocket 最简单的方法是安装一个用于发起 WebSocket 请求的命令行工具,例如 wscat (opens in a new tab)。使用 wscat,你可以按如下方式发送请求:

注意:如果你有 Alchemy 账户,你可以将 demo 替换为你自己的 API 密钥。在此处注册免费的 Alchemy 账户! (opens in a new tab)

wscat -c wss://eth-mainnet.ws.alchemyapi.io/ws/demo

>  {"jsonrpc":  "2.0", "id": 0, "method":  "eth_gasPrice"}

<  {"jsonrpc":  "2.0", "result":  "0xb2d05e00", "id": 0}

如何使用 WebSocket

首先,使用你的应用程序的 WebSocket URL 打开一个 WebSocket。你可以通过在 你的仪表板 (opens in a new tab) 中打开应用程序页面并点击“View Key”(查看密钥)来找到你的应用程序的 WebSocket URL。请注意,你的应用程序的 WebSocket URL 与其 HTTP 请求的 URL 不同,但两者都可以通过点击“View Key”找到。

Where to find your WebSocket URL in your Alchemy dashboard

Alchemy API 参考 (opens in a new tab) 中列出的任何 API 都可以通过 WebSocket 使用。为此,请使用与作为 HTTP POST 请求主体发送的相同有效载荷,但改为通过 WebSocket 发送该有效载荷。

使用 Web3

在使用像 Web3 这样的客户端库时,过渡到 WebSocket 非常简单。只需在实例化 Web3 客户端时传递 WebSocket URL 而不是 HTTP URL 即可。例如:

const web3 = new Web3("wss://eth-mainnet.ws.alchemyapi.io/ws/your-api-key")

web3.eth.getBlockNumber().then(console.log) // -> 7946893

订阅 API

通过 WebSocket 连接时,你可以使用两个额外的方法:eth_subscribeeth_unsubscribe。这些方法将允许你监听特定事件并立即收到通知。

eth_subscribe

为指定事件创建新的订阅。了解有关 eth_subscribe 的更多信息 (opens in a new tab)

参数

  1. 订阅类型
  2. 可选参数

第一个参数指定要监听的事件类型。第二个参数包含取决于第一个参数的附加选项。下面描述了不同的订阅类型、它们的选项以及它们的事件有效载荷。

返回值

订阅 ID:此 ID 将附加到任何接收到的事件中,也可用于使用 eth_unsubscribe 取消订阅。

订阅事件

在订阅处于活动状态时,你将收到事件,这些事件是具有以下字段的对象:

  • jsonrpc:始终为 "2.0"
  • method:始终为 "eth_subscription"
  • params:具有以下字段的对象:
    • subscription:由创建此订阅的 eth_subscribe 调用返回的订阅 ID。
    • result:一个对象,其内容因订阅类型而异。

订阅类型

  1. alchemy_newFullPendingTransactions

返回添加到待处理状态的所有交易的交易信息。此订阅类型订阅待处理交易,类似于标准的 Web3 调用 web3.eth.subscribe("pendingTransactions"),但不同之处在于它发出_完整的交易信息_而不仅仅是交易哈希。

示例:

  1. newHeads

只要有新区块头添加到链中,就会发出一个事件,包括在链重组期间。

当发生链重组时,此订阅将发出一个包含新链所有新区块头的事件。特别是,这意味着你可能会看到发出多个具有相同高度的区块头,当发生这种情况时,应将较晚的区块头视为重组后的正确区块头。

示例:

  1. logs

发出属于新添加区块且符合指定过滤标准的日志。

当发生链重组时,属于旧链上区块的日志将再次发出,其 removed 属性设置为 true。此外,还会发出属于新链上区块的日志,这意味着在重组的情况下,可能会多次看到同一笔交易的日志。

参数

  1. 具有以下字段的对象:
    • address(可选):表示地址的字符串或此类字符串的数组。
      • 仅发出从这些地址之一创建的日志。
    • topics:主题说明符数组。
      • 每个主题说明符要么是 null,要么是表示主题的字符串,要么是字符串数组。
      • 数组中非 null 的每个位置,都会将发出的日志限制为仅包含在该位置具有给定主题之一的日志。

主题规范的一些示例:

  • []:允许任何主题。
  • [A]:A 在第一个位置(以及之后的任何内容)。
  • [null, B]:任何内容在第一个位置,B 在第二个位置(以及之后的任何内容)。
  • [A, B]:A 在第一个位置,B 在第二个位置(以及之后的任何内容)。
  • [[A, B], [A, B]]:(A 或 B)在第一个位置,(A 或 B)在第二个位置(以及之后的任何内容)。

示例:

eth_unsubscribe

取消现有订阅,以便不再发送任何事件。

参数

  1. 订阅 ID,即先前从 eth_subscribe 调用返回的 ID。

返回值

如果成功取消订阅,则返回 true;如果不存在具有给定 ID 的订阅,则返回 false

示例:

请求

curl https://eth-mainnet.alchemyapi.io/v2/your-api-key
-X POST
-H "Content-Type: application/json"
-d '{"id": 1, "method": "eth_unsubscribe", "params": ["0x9cef478923ff08bf67fde6c64013158d"]}'

结果

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": true
}

免费 注册 Alchemy (opens in a new tab),查看 我们的文档 (opens in a new tab),如需获取最新消息,请在 推特 (opens in a new tab) 上关注我们。