跳转至主要内容

使用WebSocket

alchemywebsocketqueryingjavascript
初学者
Elan Halpern
Alchemy 文档(opens in a new tab)
2020年12月1日
8 分钟阅读 minute read

这是有关使用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)

1wscat -c wss://eth-mainnet.ws.alchemyapi.io/ws/demo
2
3> {"jsonrpc": "2.0", "id": 0, "method": "eth_gasPrice"}
4
5< {"jsonrpc": "2.0", "result": "0xb2d05e00", "id": 0}
6

如何使用WebSocket

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

在你的Alchemy仪表板中的何处可找到你的WebSocket URL

Alchemy API参考(opens in a new tab)中列出的的任何API都可以通过WebSocket使用。 为此,请使用与HTTP POST请求正文相同的有效载荷,而不是通过WebSocket发送该有效负载。

使用Web3

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

1const web3 = new Web3("wss://eth-mainnet.ws.alchemyapi.io/ws/your-api-key")
2
3web3.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> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["alchemy_newFullPendingTransactions"]}
2
3< {"id":1,"result":"0x9a52eeddc2b289f985c0e23a7d8427c8","jsonrpc":"2.0"}
4< {
5 "jsonrpc":"2.0",
6 "method":"eth_subscription",
7 "params":{
8 "result":{
9 "blockHash":null,
10 "blockNumber":null,
11 "from":"0xa36452fc31f6f482ad823cd1cf5515177d57667f",
12 "gas":"0x1adb0",
13 "gasPrice":"0x7735c4d40",
14 "hash":"0x50bff0736c713458c92dd1848d12f3354149be1363123dae35e94e0f2a9d56bf",
15"input":"0xa9059cbb0000000000000000000000000d0707963952f2fba59dd06f2b425ace40b492fe0000000000000000000000000000000000000000000015b1111266cfca100000",
16 "nonce":"0x0",
17 "to":"0xea38eaa3c86c8f9b751533ba2e562deb9acded40",
18 "transactionIndex":null,
19 "value":"0x0",
20 "v":"0x26",
21 "r":"0x195c2c1ed126088e12d290aa93541677d3e3b1d10f137e11f86b1b9227f01e3b",
22 "s":"0x60fc4edbf1527832a2a36dbc1e63ed6193a6eee654472fbebbf88ef1750b5344"},
23 "subscription":"0x9a52eeddc2b289f985c0e23a7d8427c8"
24 }
25 }
26
显示全部
复制
  1. newHeads

每当向链中添加新标头时(包括在链重组期间)都会触发事件。

发生链重组时,此订阅将触发一个事件,其中包含新链的所有新标头。 具体地说,这意味着你可能会看到多个高度相同的标头,当发生这种情况时,应该将后一个标头视为重组后的正确标头。

示例:

1> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
2
3< {"jsonrpc":"2.0","id":2,"result":"0x9ce59a13059e417087c02d3236a0b1cc"}
4< {
5 "jsonrpc": "2.0",
6 "method": "eth_subscription",
7 "params": {
8 "result": {
9 "extraData": "0xd983010305844765746887676f312e342e328777696e646f7773",
10 "gasLimit": "0x47e7c4",
11 "gasUsed": "0x38658",
12 "logsBloom":
13"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
14 "nonce": "0x084149998194cc5f",
15 "number": "0x1348c9",
16 "parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701",
17 "receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36",
18 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
19 "stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378",
20 "timestamp": "0x56ffeff8",
21 "transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f"
22 },
23 "subscription": "0x9ce59a13059e417087c02d3236a0b1cc"
24 }
25}
26
显示全部
复制
  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)位于第二个位置(以及后面任何位置)。

示例:

1> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}
2
3< {"jsonrpc":"2.0","id":2,"result":"0x4a8a4c0517381924f9838102c5a4dcb7"}
4< {
5 "jsonrpc": "2.0",
6 "method": "eth_subscription",
7 "params": {
8 "subscription": "0x4a8a4c0517381924f9838102c5a4dcb7",
9 "result": {
10 "address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",
11 "blockHash": "0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04",
12 "blockNumber": "0x29e87",
13 "data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003",
14 "logIndex":"0x0",
15 "topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],
16 "transactionHash": "0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4",
17 "transactionIndex": "0x0"
18 }
19 }
20}
21
显示全部
复制

eth_unsubscribe

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

参数

  1. 先前从eth_comment调用返回的订阅ID。

返回

如果订阅成功取消则为true,或者,如果没有具有给定ID的订阅,则为false

示例:

请求

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

结果

1{
2 "jsonrpc": "2.0",
3 "id": 1,
4 "result": true
5}
复制

免费注册 Alchemy(opens in a new tab),查看我们的相关文档(opens in a new tab),并关注我们的 Twitter(opens in a new tab) 了解最新消息。

上次修改时间: @pettinarip(opens in a new tab), 2023年12月8日

本教程对你有帮助吗?