跳至主要內容

使用 WebSockets

Alchemy
websockets
查詢
JavaScript
初階
伊蘭·哈爾彭
2020年12月1日
10 分鐘閱讀

這是一份使用 WebSockets 向以太坊區塊鏈發出請求的入門指南。這些範例使用標準的 JSON-RPC 方法,因此它們適用於任何提供 WebSocket 端點的節點或節點提供者,包括 Alchemy。

 (在新分頁開啟)WebSockets 與 HTTP 的比較

與 HTTP 不同,使用 WebSockets 時,當你需要特定資訊時,不需要持續發出請求。WebSockets 會為你維持網路連線(如果設定正確的話)並監聽變更。

與任何網路連線一樣,你不應假設 WebSocket 會永遠保持開啟而不中斷,但手動正確處理斷線和重新連線可能具有挑戰性。WebSockets 的另一個缺點是,你不會在回應中獲得 HTTP 狀態碼,而只會收到錯誤訊息。

客戶端函式庫可以為你處理這個問題。例如,Viem 的 WebSocket 傳輸 (在新分頁開啟)會在 socket 失敗時重新連線,並預設發送 keep-alive ping。

試試看

你需要一個以太坊節點的 WebSocket URL。當你建立應用程式介面 (API) 金鑰時,節點提供者會給你一個,通常格式為 wss://<provider-host>/<your-api-key>。例如,Alchemy 的以太坊主網 URL 看起來像 wss://eth-mainnet.g.alchemy.com/v2/<your-api-key>(註冊免費的 Alchemy 帳戶 (在新分頁開啟))。請參閱節點即服務以了解其他提供者,或使用你自己的節點的 WebSocket 端點。像 wss://ethereum-rpc.publicnode.com 這樣的公共端點也適用於快速實驗,但它們有速率限制,且可能不支援每種訂閱類型。

測試 WebSockets 最簡單的方法是安裝一個用於發出 WebSocket 請求的命令列工具,例如 wscat (在新分頁開啟)。使用 wscat,你可以如下發送請求:

npx wscat -c wss://<provider-host>/<your-api-key>

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

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

以 > 開頭的行是你輸入的內容,以 < 開頭的行是節點傳回的內容。

如何使用 WebSockets

首先,使用你的提供者的 WebSocket URL 開啟 WebSocket。使用 Alchemy 時,你可以透過在儀表板 (在新分頁開啟)中開啟你的應用程式並檢視其應用程式介面 (API) 金鑰來找到它。請注意,WebSockets 的 URL (wss://) 與 HTTP 請求的 URL (https://) 不同,儘管大多數提供者對兩者使用相同的 API 金鑰。

你的提供者支援的任何 JSON-RPC 方法都可以透過 WebSocket 使用。為此,請使用與作為 HTTP POST 請求主體發送的相同有效負載,但改為透過 WebSocket 發送該有效負載。

使用 Web3

在使用像 Viem (在新分頁開啟) 這樣的客戶端函式庫時,轉換到 WebSockets 很簡單。將 webSocket 傳輸與你的 WebSocket URL 一起使用,而不是使用 http 傳輸。例如,在 npm install viem 之後,將其儲存為 index.mjs 並執行 node index.mjs:

訂閱 API

透過 WebSocket 連線時,你可以使用兩個額外的方法:eth_subscribe 與 eth_unsubscribe。這些方法將允許你監聽特定事件並立即收到通知。

eth_subscribe

為指定的事件建立新的訂閱。了解更多關於 eth_subscribe 的資訊 (在新分頁開啟)。

參數

  1. 訂閱類型
  2. 選擇性參數

第一個參數指定要監聽的事件類型。第二個參數包含取決於第一個參數的額外選項。不同的訂閱類型、其選項以及其事件有效負載說明如下。

回傳值

訂閱 ID:此 ID 將附加到任何接收到的事件中,也可以用來透過 eth_unsubscribe 取消訂閱。

訂閱事件

當訂閱處於活動狀態時,你將收到事件,這些事件是具有以下欄位的物件:

  • jsonrpc:始終為 "2.0"
  • method:始終為 "eth_subscription"
  • params:具有以下欄位的物件:
    • subscription:由建立此訂閱的 eth_subscribe 呼叫所回傳的訂閱 ID。
    • result:其內容根據訂閱類型而有所不同的物件。

訂閱類型

  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)在第二個位置(以及之後的任何內容)。

範例:

此範例監聽以太坊主網上 WETH 合約 (在新分頁開啟)的 Deposit 事件:

  1. newPendingTransactions

發出新增到節點待處理狀態(其記憶體池)的每筆交易的雜湊。

範例:

> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}

< {"jsonrpc":"2.0","result":"0x1c2365b029179adf1e84b9e327315249","id":1}
< {"jsonrpc":"2.0","method":"eth_subscription","params":{"result":"0x4a62d0ad7c8868fbbfa10604e68638e637c6fc6f64fd1fb4ca042dcd0158c992","subscription":"0x1c2365b029179adf1e84b9e327315249"}}

一些提供者也提供他們自己的訂閱類型。例如,Alchemy 的 alchemy_pendingTransactions (在新分頁開啟) 發出完整的交易物件而不僅僅是雜湊,並接受選擇性的 fromAddress、toAddress 和 hashesOnly 過濾器。這些不是標準 JSON-RPC 應用程式介面 (API) 的一部分,因此它們僅適用於該提供者。

eth_unsubscribe

取消現有的訂閱,以便不再發送任何事件。

參數

  1. 訂閱 ID,如先前從 eth_subscribe 呼叫所回傳。

回傳值

如果成功取消訂閱,則為 true;如果不存在具有給定 ID 的訂閱,則為 false。

訂閱僅存在於建立它的 WebSocket 連線上,因此必須透過該相同連線發送 eth_unsubscribe。它不能作為單獨的 HTTP 請求發送。關閉連線也會取消其所有訂閱。

範例:

> {"jsonrpc": "2.0", "id": 2, "method": "eth_unsubscribe", "params": ["0xe0d4abf5caf333fbf94c5f02182e6469"]}

< {"jsonrpc":"2.0","result":true,"id":2}

免費註冊 Alchemy (在新分頁開啟),查看 Alchemy 的文件 (在新分頁開啟),如需最新消息,請在推特 (在新分頁開啟)上追蹤 Alchemy。