WebSocket Abonelikleri

eth_subscribe newHeads ve logs için BlockVectra WebSocket uç noktalarına bağlanın. Bağlantı yöntemlerini, filtre kurallarını, yeniden bağlanma geri çekilmesini ve kurtarmayı öğrenin.

BlockVectra, standart JSON-RPC isteklerinin yanı sıra gerçek zamanlı Ethereum olay abonelikleri akışı için güvenli WebSocket bağlantıları (wss://) sağlar.

WebSocket, Webhook veya yoklama arasında seçim yapma

Uygulamanız bir bağlantıyı canlı tutabildiğinde gerçek zamanlı newHeads ve filtrelenmiş logs için WebSocket kullanın. İzlenen cüzdan etkinliğini bir HTTPS uç noktasında ham gövde imza doğrulaması, yeniden denemeler ve saklanan eşleşmelerin yeniden oynatılmasıyla (replay) almak için Blockchain Webhook API'sini kullanın. Zamanlanmış ERC-20 ödeme takibi ve geçmiş logları geriye dönük doldurma için HTTP yoklamasını kullanın. Stablecoin rehberi ayrıca bir USDT / USDC Webhook alıcısını gösterir. Geliştiriciler ve AI Agent'lar için zincir desteği, alıcı gereksinimleri ve kurtarma dengeleri genelinde mimari bir karşılaştırma için Webhooks, WebSocket veya RPC yoklama seçme rehberine bakın.

WebSocket desteği GET /v1/chains içindeki ws ve subscriptions alanlarından gelir; Push desteği ise kimliği doğrulanmış GET /v1/push/chains listesinden gelir. WebSocket desteği olmayan bir zincir, bu listede yer alıyorsa yine de adres Webhook'larını kullanabilir.

WebSocket bağlantı kesilmeleri yeniden abone olmayı ve geriye dönük doldurmayı gerektirir; Push kontrol olayları olan subscription.gap veya chain.reorg olaylarını yayınlamazlar. Webhook'lar için bir boşluk aralık taraması gerektirir; bir reorg bildirimi, otomatik olarak yeniden iletilen kanonik olayları saklamadan önce değiştirilen olayların işaretlenmesini veya atılmasını gerektirir. Push yeniden oynatma (replay), bir adres veya zincir eklenmeden önceki ya da abonelik çevrimdışıyken gerçekleşen verileri değil, saklanan eşleşmeleri yeniden gönderir. Kurtarmayı uygularken faturalandırma kurallarını ve hata referansını inceleyin.

Kullanılabilir zincirler

GET /v1/chains içinde ws (boolean) ve subscriptions (desteklenen türlerin dizisi) alanlarını okuyarak bir ağda WebSocket aboneliklerinin etkin olup olmadığını kontrol edebilirsiniz.

Aşağıdaki tablo, WebSocket desteğinin etkin olduğu ağları yansıtmaktadır:

ZincirWebSocket Uç Noktası (Yol Anahtarı)
Robinhood Chainwss://api.blockvectra.com/v1/robinhood_mainnet/{api_key}
Robinhood Chain Testnetwss://api.blockvectra.com/v1/robinhood_testnet/{api_key}

Bağlantı ve kimlik doğrulama

İstemciler güvenli bir TLS WebSocket bağlantısı (wss://) kurar. API key iki şekilde sağlanabilir:

  • Yol anahtarı (Path key): wss://api.blockvectra.com/v1/{chain}/{api_key}
  • Başlık anahtarı (Header key): HTTP Upgrade el sıkışması sırasında x-api-key: {api_key} veya Authorization: Bearer {api_key} başlığı ile wss://api.blockvectra.com/v1/{chain}.

Bir yol anahtarı ile yol anahtarı kullanılır ve her iki kimlik doğrulama başlığı da yoksayılır. Bir yol anahtarı olmadığında, boş olmayan bir x-api-key başlığı Authorization: Bearer başlığına göre önceliklidir. Tarayıcı WebSocket API'leri bu başlıkları ayarlayamaz; yol anahtarlı URL'yi kullanın.

El sıkışma (handshake) kabul kontrolleri

El sıkışma şu nedenlerle başarısız olabilir:

  • Kimlik doğrulama: Bulunmayan bir API key HTTP 401 (missing_api_key) döndürür; bilinmeyen, devre dışı bırakılmış veya iptal edilmiş bir API key HTTP 401 (invalid_api_key) döndürür; kimlik doğrulama geçici olarak kullanılamıyorsa yanıt HTTP 503 (auth_unavailable) olur.
  • Hesap bakiyesi: Sıfır veya negatif ön ödemeli bakiyesi olan bir hesap HTTP 402 (balance_exhausted) döndürür; faturalandırma durumu onaylanamıyorsa yanıt HTTP 503 (billing_unavailable) olur.
  • Bağlantı sınırları: Anahtar başına sınırın (20 bağlantı) veya hesap başına sınırın (50 bağlantı) aşılması HTTP 429 (ws_connection_limit) döndürür.
  • Zincir kullanılabilirliği: Bilinmeyen veya hizmet verilmeyen bir zincirin istenmesi HTTP 404 (unknown_chain) döndürür.
  • Sunucu kapasitesi: Sunucu meşgul veya aşırı yüklendiğinde, el sıkışma bir Retry-After başlığı ile birlikte HTTP 503 (overloaded) döndürür.

Bağlantı kurulduktan sonra istemciler, standart JSON-RPC 2.0 isteklerini (eth_blockNumber veya eth_call gibi) ve UTF-8 metin çerçeveleri olarak biçimlendirilmiş abonelik kontrol yöntemlerini gönderebilir.

Faturalandırma kuralları

  • Bağlantı kurmak, boşta bir bağlantıyı açık tutmak ve ping/pong bağlantı sinyalleri faturalandırılmaz.
  • false döndüren bir abonelik iptali de dahil olmak üzere başarılı eth_subscribe ve eth_unsubscribe çağrıları faturalandırılır; başarısız çağrılar faturalandırılmaz. Sıradan JSON-RPC çağrıları JSON-RPC faturalandırma kurallarını takip eder.
  • newHeads bildirimleri, bağlantının kaç tane newHeads aboneliğine sahip olduğuna bakılmaksızın, bağlantı başına blok karması başına bir kez sayılır.
  • logs bildirimleri, eşleşen loglara sahip blok karması ve aşaması başına abonelik başına bir kez sayılır; eşleşme olmayan bloklar faturalandırılmaz. Aynı blokta ve aşamada birden fazla eşleşen log olması ücreti katlamaz. Ayrı abonelikler, filtreleri örtüşse bile ayrı sayılır. Yeniden düzenleme logları (removed: true) ayrı bir birim oluşturur; aynı yükseklikteki yeni bir blok farklı bir karmaya sahiptir ve farklı bir birimdir.
  • Bildirimler yalnızca soket gönderme arabelleğine başarıyla aktarıldıktan sonra faturalandırılır; kuyruğa alınan ancak aktarılmayan veya bırakılan bildirimler faturalandırılmaz. Bir eth_unsubscribe yanıtından önce kuyruğa alınan bildirimler aktarılmışsa sayılır. WebSocket mesajları hiçbir HTTP faturalandırma başlığı taşımaz; ölçülen CU için hesap kullanımına danışın.

Abonelik yöntemleri

API standart Ethereum pub/sub arayüzünü uygular: eth_subscribe ve eth_unsubscribe.

newHeads

Zincir tepesine yeni bir blok eklendiğinde yeni bir blok başlığı nesnesi yayınlar.

  • Abone olma isteği:
    {"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}
  • Abone olma yanıtı: Opak bir onaltılık abonelik tanımlayıcısı döndürür:
    {"jsonrpc":"2.0","id":1,"result":"0x1"}
  • Push bildirim çerçevesi:
    {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}

logs

Belirtilen filtre ölçütleriyle eşleşen log olaylarını yayınlar.

  • Filtre gereksinimi: Her logs abonelik filtresi bir address (bir sözleşme adresi veya adres dizisi) veya bir topic0 (ilk topic konumu, null olmayan) belirtmelidir. Hiçbirini belirtmeyen bir filtre ({} veya {"topics":[null,"0x..."]} gibi), -32602 (logs_filter_required) hata koduyla reddedilir.

  • Filtre sınırları: En fazla 100 adres; konum başına en fazla 16 aday karma ile en fazla 4 topic konumu.

  • Filtre kapasitesi: Aktif log filtreleri kapasiteye ulaşırsa, abonelik -32022 (ws_filter_capacity) hata kodunu döndürür.

  • Zincir yeniden düzenlemeleri (reorg): Bir blok zincir reorg'u nedeniyle kaldırılırsa, kaldırılan loglar için log bildirimleri "removed": true taşır.

  • Abone olma isteği:

    {"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}

eth_unsubscribe

Abonelik tanımlayıcısını kullanarak etkin bir aboneliği sonlandırır.

  • Abonelikten çıkma isteği:
    {"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]}
  • Abonelikten çıkma yanıtı:
    {"jsonrpc":"2.0","id":3,"result":true}

Çalıştırılabilir örnekler

createPublicClient ve webSocket aktarımı aracılığıyla viem v2 kullanarak bağlanın. {chain} değerini hedef zincir tanımlayıcısıyla ve {api_key} değerini API key'inizle değiştirin:

import { createPublicClient, webSocket } from 'viem';

const apiKey = process.env.BLOCKVECTRA_API_KEY || '{api_key}';
const url = `wss://api.blockvectra.com/v1/robinhood_mainnet/${apiKey}`;

const client = createPublicClient({
  transport: webSocket(url),
});

// 1. Yeni blok başlıklarına abone olun (newHeads)
const unwatchBlocks = client.watchBlocks({
  onBlock: (block) => {
    console.log('Yeni blok başlığı alındı:', block.number, block.hash);
  },
  onError: (error) => {
    console.error('watchBlocks hatası:', error);
  },
});

// 2. Sözleşme olay loglarına abone olun (filtre address veya topic0 gerektirir)
const unwatchEvents = client.watchEvent({
  address: '0x1234567890123456789012345678901234567890',
  onLogs: (logs) => {
    console.log('Eşleşen loglar alındı:', logs);
  },
  onError: (error) => {
    console.error('watchEvent hatası:', error);
  },
});

Kapanış kodları ve istemci eylemleri

Sunucu bir WebSocket oturumunu sonlandırdığında, belirli bir kapanış kodu ve kısa bir neden içeren bir Kapanış (Close) çerçevesi gönderir. Aşağıdaki tablo, sunucu tarafından iletilen kapanış kodlarını ve önerilen eylemleri listeler:

Kapanış koduNeden dizesiAçıklamaYeniden denenebilirİstemci eylemi
1001idle3600 saniye (1 saat) boyunca abonelik veya mesaj içermeyen etkin olmayan bağlantıEvetGerektiğinde yeniden bağlanın.
1003binary frames are not acceptedİkili (binary) WebSocket çerçevesi alındı; yalnızca UTF-8 metin çerçeveleri kabul edilirHayırOtomatik olarak yeniden bağlanmayın. İstemciyi metin çerçeveleri gönderecek şekilde güncelleyin.
1009message too largeGelen yük (payload) 1 MiB sınırını aştıHayırOtomatik olarak yeniden bağlanmayın. Büyük istekleri bölün veya yük boyutunu azaltın.
1012service restartSunucu yeniden başlatılıyor veya oturum maksimum yaşam süresine (24 saat) ulaştıEvetRastgele gecikmeli (jitter) geri çekilme kullanarak yeniden bağlanın, abonelikleri yeniden oluşturun ve kaçırılan verileri geriye dönük doldurun.
1013chain unavailableZincir kullanılamıyorEvetTam gecikmeli (full-jitter) üstel geri çekilme kullanarak yeniden bağlanın, abonelikleri yeniden oluşturun ve kaçırılan verileri geriye dönük doldurun.
1013overloadedSunucu geçici olarak aşırı yüklendiEvetTam gecikmeli (full-jitter) üstel geri çekilme kullanarak yeniden bağlanın, abonelikleri yeniden oluşturun ve kaçırılan verileri geriye dönük doldurun.
4402insufficient balanceHesap bakiyesi tükendiHayırOtomatik olarak yeniden bağlanmayın. Bakiyenizi yükleyin, ardından yeniden bağlanın.
4404invalid api keyAPI key bilinmiyor, devre dışı bırakılmış veya iptal edilmişHayırOtomatik olarak yeniden bağlanmayın. Yeniden bağlanmadan önce konsolda API key'i doğrulayın veya yenileyin.
4408slow consumerSunucu, push kuyruğu 512 KiB'yi geçen oturumu kapatır ve bekleyen bildirimleri bırakır; istemciler bir kapanış çerçevesi almayabilir (tarayıcı 1006 bildirir)EvetBeklenmeyen bağlantı kesilmelerini (kapanış çerçevesi alınmadı, tarayıcı 1006 bildiriyor) 4408 gibi ele alın: geri çekilme ile yeniden bağlanın, abonelikleri yeniden oluşturun ve bırakılan verileri eth_getLogs ile doldurun; daha azına abone olun veya daha hızlı okuyun.
4429push rate exceededBildirim hızı 1,000 push/saniye sınırını aştıEvetAbonelikleri azaltın veya filtreleri daraltın; geri çekilme ile yeniden bağlanın, yeniden abone olun ve geriye dönük doldurun.
4503billing unavailableFaturalandırma geçici olarak kullanılamıyorEvetGeçici durum; tam gecikmeli (full-jitter) üstel geri çekilme kullanarak yeniden bağlanın.

Yeniden bağlanma ve üstel geri çekilme

Bağlantılar koptuğunda senkronize yeniden bağlanma fırtınalarını önlemek için istemciler tam gecikmeli (full-jitter) üstel geri çekilme uygulamalıdır:

  • Geri çekilme formülü: n'inci yeniden bağlanma girişiminden önce (n = 0, 1, 2, ...), rastgele ve tekdüze (uniformly at random) seçilen bir süre boyunca bekleyin:
    delay = random(0, min(20s, 0.5s * 2^n))
  • Sayacı sıfırlama: Yeniden deneme sayacı n'i yalnızca en az 60 saniye boyunca kesintisiz, kararlı bir bağlantıyı sürdürdükten sonra 0'a sıfırlayın.
  • Kapanış kodu 1012: Senkronize yeniden bağlanma artışlarını önlemek için ilk yeniden bağlanma girişiminden önce rastgele bir başlangıç gecikmesi uygulayın.
  • Yeniden denenemeyen kodlar: 4402, 4404, 1003 veya 1009 durumlarında otomatik olarak yeniden bağlanmayın.

Yeniden bağlandıktan sonra kaçırılan verileri geriye dönük doldurma

WebSocket abonelikleri bağlantılar boyunca kalıcı değildir; bir bağlantı kesintisi sırasında yayınlanan bildirimler sunucuda tutulmaz. Yeniden bağlanmanın ardından istemciler bir yakalama (catch-up) stratejisi yürütmelidir:

  1. eth_getLogs ile logları geriye dönük doldurma:
    • Başarıyla işlenen en yüksek blok numarasını (last_processed_block) kalıcı olarak saklayın.
    • Canlı olayları yakalamak için yeniden bağlanma anında hemen eth_subscribe("logs", ...) çağrısı yapın.
    • fromBlock: last_processed_block + 1 ve toBlock: "latest" (veya canlı akıştan alınan ilk blok) ile eth_getLogs aracılığıyla kaçırılan blokları sorgulayın.
    • Bağlantı kesintisi boşluğu ağın max_logs_block_range değerini (GET /v1/chains üzerinden) aşıyorsa, sorguları bu sınırı aşmayan parçalara bölün.
    • Benzersiz demet (blockHash, transactionHash, logIndex) kullanarak sorgu sınırı boyunca log girdilerini tekilleştirin.
  2. eth_getBlockByNumber ile blok başlıklarını geriye dönük doldurma:
    • Bağlantı kesilmeden önce alınan en son blok numarasını ve karmasını kaydedin.
    • newHeads aboneliğini yeniden başlatın.
    • eth_getBlockByNumber("latest", false) sorgulayın ve eksik ara blokları sıralı olarak getirin. Reorg'ları tespit etmek için parentHash zincir sürekliliğini doğrulayın.

Sınırlar

SınırDeğerAşıldığında sonuç
WebSocket bağlantısı başına abonelikler100-32022 subscription_limit
WebSocket bağlantısı başına newHeads abonelikleri4-32022 subscription_limit
logs abonelik filtresi gereksinimleriBir address veya topic0 (topics içindeki ilk konum) belirtmelidir-32602 logs_filter_required

Sonraki adımlar

Son güncelleme:

Bu sayfada