Przejdź do głównej treści

Korzystanie z WebSockets

Alchemy
websockets
zapytania
JavaScript
Początkujący
Elan Halpern
1 grudnia 2020
6 minut czytania

To jest przewodnik dla początkujących dotyczący korzystania z WebSockets do wysyłania żądań do blockchaina Ethereum. Przykłady wykorzystują standardowe metody JSON-RPC, więc działają z każdym węzłem lub dostawcą węzłów, który oferuje punkt końcowy WebSocket, w tym z Alchemy.

 (otwiera się w nowej karcie)WebSockets a HTTP

W przeciwieństwie do HTTP, w przypadku WebSockets nie musisz ciągle wysyłać żądań, gdy chcesz uzyskać określone informacje. WebSockets utrzymują dla Ciebie połączenie sieciowe (jeśli są zaimplementowane poprawnie) i nasłuchują zmian.

Podobnie jak w przypadku każdego połączenia sieciowego, nie należy zakładać, że WebSocket pozostanie otwarty na zawsze bez przerw, ale prawidłowe ręczne obsługiwanie zerwanych połączeń i ponownego łączenia może być trudne do poprawnego wykonania. Kolejną wadą WebSockets jest to, że nie otrzymujesz kodów statusu HTTP w odpowiedzi, a jedynie wiadomość o błędzie.

Biblioteki klienckie mogą to obsłużyć za Ciebie. Na przykład transport WebSocket biblioteki Viem (otwiera się w nowej karcie) domyślnie łączy się ponownie w przypadku awarii gniazda i wysyła pingi podtrzymujące połączenie (keep-alive).

Wypróbuj

Potrzebujesz adresu URL WebSocket dla węzła Ethereum. Dostawcy węzłów udostępniają go podczas tworzenia klucza interfejsu programowania aplikacji (API), zazwyczaj w postaci wss://<provider-host>/<your-api-key>. Na przykład adres URL sieci głównej Ethereum w Alchemy wygląda tak: wss://eth-mainnet.g.alchemy.com/v2/<your-api-key> (zarejestruj darmowe konto Alchemy (otwiera się w nowej karcie)). Zobacz węzły jako usługa, aby znaleźć innych dostawców, lub użyj punktu końcowego WebSocket własnego węzła. Publiczne punkty końcowe, takie jak wss://ethereum-rpc.publicnode.com, również sprawdzają się w szybkich eksperymentach, ale mają ograniczenia przepustowości (rate-limited) i mogą nie obsługiwać każdego typu subskrypcji.

Najprostszym sposobem na przetestowanie WebSockets jest zainstalowanie narzędzia wiersza poleceń do wysyłania żądań WebSocket, takiego jak wscat (otwiera się w nowej karcie). Używając wscat, możesz wysyłać żądania w następujący sposób:

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

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

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

Linie zaczynające się od > to to, co wpisujesz, a linie zaczynające się od < to to, co odsyła węzeł.

Jak korzystać z WebSockets

Aby rozpocząć, otwórz WebSocket, używając adresu URL WebSocket swojego dostawcy. W przypadku Alchemy możesz go znaleźć, otwierając swoją aplikację w panelu sterowania (otwiera się w nowej karcie) i wyświetlając jej klucz interfejsu programowania aplikacji (API). Zauważ, że adres URL dla WebSockets (wss://) różni się od adresu URL dla żądań HTTP (https://), chociaż większość dostawców używa tego samego klucza API dla obu.

Każda z metod JSON-RPC, którą obsługuje Twój dostawca, może być używana przez WebSocket. Aby to zrobić, użyj tego samego ładunku (payload), który zostałby wysłany jako treść żądania HTTP POST, ale zamiast tego wyślij ten ładunek przez WebSocket.

Z Web3

Przejście na WebSockets podczas korzystania z biblioteki klienckiej, takiej jak Viem (otwiera się w nowej karcie), jest proste. Użyj transportu webSocket ze swoim adresem URL WebSocket zamiast transportu http. Na przykład, po wykonaniu npm install viem, zapisz to jako index.mjs i uruchom node index.mjs:

API subskrypcji

Po połączeniu przez WebSocket możesz użyć dwóch dodatkowych metod: eth_subscribe oraz eth_unsubscribe. Metody te pozwolą Ci nasłuchiwać określonych zdarzeń i otrzymywać natychmiastowe powiadomienia.

eth_subscribe

Tworzy nową subskrypcję dla określonych zdarzeń. Dowiedz się więcej o eth_subscribe (otwiera się w nowej karcie).

Parametry

  1. Typy subskrypcji
  2. Opcjonalne parametry

Pierwszy argument określa typ zdarzenia, którego należy nasłuchiwać. Drugi argument zawiera dodatkowe opcje, które zależą od pierwszego argumentu. Różne typy subskrypcji, ich opcje i ładunki zdarzeń opisano poniżej.

Zwraca

ID subskrypcji: To ID będzie dołączone do wszystkich odebranych zdarzeń i może być również użyte do anulowania subskrypcji za pomocą eth_unsubscribe.

Zdarzenia subskrypcji

Dopóki subskrypcja jest aktywna, będziesz otrzymywać zdarzenia, które są obiektami z następującymi polami:

  • jsonrpc: Zawsze "2.0"
  • method: Zawsze "eth_subscription"
  • params: Obiekt z następującymi polami:
    • subscription: ID subskrypcji zwrócone przez wywołanie eth_subscribe, które utworzyło tę subskrypcję.
    • result: Obiekt, którego zawartość różni się w zależności od typu subskrypcji.

Typy subskrypcji

  1. newHeads

Emituje zdarzenie za każdym razem, gdy do łańcucha dodawany jest nowy nagłówek, w tym podczas reorganizacji łańcucha.

Gdy nastąpi reorganizacja łańcucha, ta subskrypcja wyemituje zdarzenie zawierające wszystkie nowe nagłówki dla nowego łańcucha. W szczególności oznacza to, że możesz zobaczyć wiele nagłówków wyemitowanych z tą samą wysokością, a gdy to nastąpi, późniejszy nagłówek powinien zostać uznany za prawidłowy po reorganizacji.

Przykład:

  1. logs

Emituje logi, które są częścią nowo dodanych bloków i pasują do określonych kryteriów filtrowania.

Gdy nastąpi reorganizacja łańcucha, logi będące częścią bloków w starym łańcuchu zostaną wyemitowane ponownie z właściwością removed ustawioną na true. Ponadto emitowane są logi będące częścią bloków w nowym łańcuchu, co oznacza, że w przypadku reorganizacji możliwe jest wielokrotne zobaczenie logów dla tej samej transakcji.

Parametry

  1. Obiekt z następującymi polami:
    • address (opcjonalnie): ciąg znaków reprezentujący adres lub tablica takich ciągów.
      • Emitowane będą tylko logi utworzone z jednego z tych adresów.
    • topics: tablica specyfikatorów tematów.
      • Każdy specyfikator tematu to null, ciąg znaków reprezentujący temat lub tablica ciągów znaków.
      • Każda pozycja w tablicy, która nie jest null, ogranicza emitowane logi tylko do tych, które mają jeden z podanych tematów na tej pozycji.

Kilka przykładów specyfikacji tematów:

  • []: Dozwolone dowolne tematy.
  • [A]: A na pierwszej pozycji (i cokolwiek po nim).
  • [null, B]: Cokolwiek na pierwszej pozycji i B na drugiej pozycji (i cokolwiek po nim).
  • [A, B]: A na pierwszej pozycji i B na drugiej pozycji (i cokolwiek po nim).
  • [[A, B], [A, B]]: (A lub B) na pierwszej pozycji i (A lub B) na drugiej pozycji (i cokolwiek po nim).

Przykład:

Ten przykład nasłuchuje zdarzeń Deposit z kontraktu WETH (otwiera się w nowej karcie) w sieci głównej Ethereum:

  1. newPendingTransactions

Emituje hash każdej transakcji, która jest dodawana do oczekującego stanu węzła (jego mempool).

Przykład:

> {"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"}}

Niektórzy dostawcy oferują również własne typy subskrypcji. Na przykład alchemy_pendingTransactions (otwiera się w nowej karcie) od Alchemy emituje pełne obiekty transakcji zamiast tylko hashów i akceptuje opcjonalne filtry fromAddress, toAddress oraz hashesOnly. Nie są one częścią standardowego interfejsu programowania aplikacji (API) JSON-RPC, więc działają tylko z tym dostawcą.

eth_unsubscribe

Anuluje istniejącą subskrypcję, dzięki czemu nie są wysyłane żadne kolejne zdarzenia.

Parametry

  1. ID subskrypcji, zwrócone wcześniej z wywołania eth_subscribe.

Zwraca

true, jeśli subskrypcja została pomyślnie anulowana, lub false, jeśli nie istniała subskrypcja o podanym ID.

Subskrypcja istnieje tylko w połączeniu WebSocket, które ją utworzyło, więc eth_unsubscribe musi zostać wysłane przez to samo połączenie. Nie można go wysłać jako oddzielnego żądania HTTP. Zamknięcie połączenia anuluje również wszystkie jego subskrypcje.

Przykład:

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

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

Zarejestruj się w Alchemy (otwiera się w nowej karcie) za darmo, sprawdź dokumentację Alchemy (otwiera się w nowej karcie) i śledź Alchemy na Twitterze (otwiera się w nowej karcie), aby być na bieżąco z najnowszymi wiadomościami.