Langganan WebSocket
Hubungkan ke endpoint WebSocket BlockVectra untuk eth_subscribe newHeads dan logs. Pelajari metode koneksi, aturan filter, backoff penyambungan kembali, dan pemulihan.
BlockVectra menyediakan koneksi WebSocket aman (wss://) untuk streaming langganan peristiwa Ethereum secara real-time bersama permintaan JSON-RPC standar.
Memilih WebSocket, Webhook, atau polling
Gunakan WebSocket untuk newHeads langsung dan logs terfilter ketika aplikasi Anda dapat mempertahankan koneksi. Gunakan Blockchain Webhook API untuk menerima aktivitas dompet yang dipantau di endpoint HTTPS, dengan verifikasi tanda tangan body mentah, percobaan ulang, dan replay kecocokan yang disimpan. Gunakan polling HTTP untuk pemantauan pembayaran ERC-20 terjadwal dan backfill log historis. Panduan stablecoin juga menunjukkan penerima Webhook USDT / USDC. Untuk perbandingan arsitektur berdasarkan dukungan chain, persyaratan penerima, dan kompromi pemulihan bagi pengembang dan AI Agent, lihat panduan memilih Webhook, WebSocket, atau polling RPC.
Dukungan WebSocket berasal dari ws dan subscriptions dalam GET /v1/chains; dukungan Push berasal dari daftar GET /v1/push/chains yang memerlukan autentikasi. Chain tanpa WebSocket tetap dapat menggunakan Webhook alamat jika tercantum di sana.
Koneksi WebSocket yang terputus memerlukan langganan ulang dan backfill; koneksi tersebut tidak menerbitkan peristiwa kontrol Push subscription.gap atau chain.reorg. Untuk Webhook, celah memerlukan pemindaian rentang; pemberitahuan reorg memerlukan peristiwa yang diganti ditandai atau dibuang sebelum menyimpan peristiwa kanonis yang dikirim ulang otomatis. Replay Push mengirim ulang kecocokan yang disimpan, bukan data sebelum alamat atau chain ditambahkan atau saat langganan offline. Tinjau aturan penagihan dan referensi error saat mengimplementasikan pemulihan.
Chain yang tersedia
Anda dapat memeriksa apakah langganan WebSocket aktif di suatu jaringan dengan membaca ws (boolean) dan subscriptions (array tipe yang didukung) dalam GET /v1/chains.
Tabel di bawah mencerminkan jaringan dengan dukungan WebSocket yang diaktifkan:
| Rantai | Endpoint WebSocket (kunci di path) |
|---|---|
| Robinhood Chain | wss://api.blockvectra.com/v1/robinhood_mainnet/{api_key} |
| Robinhood Chain Testnet | wss://api.blockvectra.com/v1/robinhood_testnet/{api_key} |
Koneksi dan autentikasi
Klien membuat koneksi WebSocket TLS aman (wss://). API key dapat disediakan dengan dua cara:
- API key pada jalur:
wss://api.blockvectra.com/v1/{chain}/{api_key} - API key pada header:
wss://api.blockvectra.com/v1/{chain}dengan headerx-api-key: {api_key}atauAuthorization: Bearer {api_key}saat handshake HTTP Upgrade.
Jika API key ada pada jalur, API key tersebut digunakan dan kedua header autentikasi diabaikan. Tanpa API key pada jalur, x-api-key yang tidak kosong diprioritaskan dibandingkan Authorization: Bearer. API WebSocket browser tidak dapat mengatur header ini; gunakan URL dengan API key pada jalur.
Pemeriksaan penerimaan handshake
Handshake dapat gagal dengan:
- Autentikasi: API key yang tidak disertakan mengembalikan HTTP 401 (
missing_api_key); API key yang tidak dikenal, dinonaktifkan, atau dicabut mengembalikan HTTP 401 (invalid_api_key); jika autentikasi tidak tersedia sementara, responsnya HTTP 503 (auth_unavailable). - Saldo akun: Akun dengan saldo prabayar nol atau negatif mengembalikan HTTP 402 (
balance_exhausted); jika state penagihan tidak dapat dipastikan, responsnya HTTP 503 (billing_unavailable). - Batas koneksi: Melampaui batas per API key (20 koneksi) atau batas per akun (50 koneksi) mengembalikan HTTP 429 (
ws_connection_limit). - Ketersediaan chain: Meminta chain yang tidak dikenal atau tidak dilayani mengembalikan HTTP 404 (
unknown_chain). - Kapasitas server: Ketika server sibuk atau kelebihan beban, handshake mengembalikan HTTP 503 (
overloaded) dengan headerRetry-After.
Setelah terhubung, klien dapat mengirim permintaan JSON-RPC 2.0 standar (seperti eth_blockNumber atau eth_call) dan metode kontrol langganan dalam format frame teks UTF-8.
Aturan penagihan
- Membuat koneksi, mempertahankan koneksi yang tidak aktif, dan heartbeat ping/pong tidak ditagih.
- Panggilan
eth_subscribedaneth_unsubscribeyang berhasil ditagih, termasuk pembatalan langganan yang mengembalikanfalse; panggilan gagal tidak ditagih. Panggilan JSON-RPC biasa mengikuti aturan penagihan JSON-RPC. - Notifikasi
newHeadsdihitung sekali per hash blok per koneksi, terlepas dari jumlah langganannewHeadspada koneksi tersebut. - Notifikasi
logsdihitung sekali per langganan per hash blok dan fase yang memiliki log cocok; blok tanpa kecocokan tidak ditagih. Beberapa log yang cocok dalam blok dan fase yang sama tidak melipatgandakan biaya. Langganan terpisah dihitung secara terpisah, meskipun filternya tumpang tindih. Log reorganisasi (removed: true) membentuk unit terpisah; blok pengganti pada tinggi yang sama memiliki hash berbeda dan merupakan unit berbeda. - Notifikasi hanya ditagih setelah berhasil ditulis ke buffer pengiriman socket; notifikasi dalam antrean atau yang dibuang tanpa ditulis tidak ditagih. Notifikasi yang masuk antrean sebelum jawaban
eth_unsubscribedihitung jika ditulis. Pesan WebSocket tidak membawa header penagihan HTTP; lihat penggunaan akun untuk CU yang diukur.
Metode langganan
API mengimplementasikan antarmuka pub/sub Ethereum standar: eth_subscribe dan eth_unsubscribe.
newHeads
Menerbitkan objek header blok baru setiap kali blok baru ditambahkan ke head chain.
- Permintaan langganan:
{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]} - Respons langganan: Mengembalikan pengenal langganan heksadesimal yang bersifat opaque:
{"jsonrpc":"2.0","id":1,"result":"0x1"} - Frame notifikasi push:
{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}
logs
Menerbitkan peristiwa log yang cocok dengan kriteria filter yang ditentukan.
-
Persyaratan filter: Setiap filter langganan
logsharus menentukanaddress(alamat kontrak atau array alamat) atautopic0(posisi topic pertama, bukan null). Filter yang tidak menentukan keduanya (seperti{}atau{"topics":[null,"0x..."]}) ditolak dengan kode error-32602(logs_filter_required). -
Batas filter: Maksimal 100 alamat; maksimal 4 posisi topic dengan maksimal 16 hash kandidat per posisi.
-
Kapasitas filter: Jika filter log aktif mencapai kapasitas, langganan mengembalikan kode error
-32022(ws_filter_capacity). -
Reorganisasi chain: Jika blok dihapus akibat reorg chain, notifikasi log untuk log yang dihapus membawa
"removed": true. -
Permintaan langganan:
{"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}
eth_unsubscribe
Mengakhiri langganan aktif menggunakan pengenal langganannya.
- Permintaan pembatalan langganan:
{"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]} - Respons pembatalan langganan:
{"jsonrpc":"2.0","id":3,"result":true}
Contoh yang dapat dijalankan
Hubungkan menggunakan viem v2 melalui createPublicClient dan transport webSocket. Ganti {chain} dengan pengenal chain tujuan dan {api_key} dengan API key Anda:
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. Subscribe to new block headers (newHeads)
const unwatchBlocks = client.watchBlocks({
onBlock: (block) => {
console.log('New block header received:', block.number, block.hash);
},
onError: (error) => {
console.error('watchBlocks error:', error);
},
});
// 2. Subscribe to contract event logs (filter requires address or topic0)
const unwatchEvents = client.watchEvent({
address: '0x1234567890123456789012345678901234567890',
onLogs: (logs) => {
console.log('Matching logs received:', logs);
},
onError: (error) => {
console.error('watchEvent error:', error);
},
});Kode penutupan dan tindakan klien
Ketika server mengakhiri sesi WebSocket, server mengirim frame Close dengan kode penutupan tertentu dan alasan singkat. Tabel di bawah mencantumkan kode penutupan yang diterbitkan server dan tindakan yang disarankan:
| Kode penutupan | String alasan | Keterangan | Dapat dicoba ulang | Tindakan klien |
|---|---|---|---|---|
| 1001 | idle | Koneksi tidak aktif tanpa langganan atau pesan selama 3600 detik (1 jam) | Ya | Sambungkan kembali sesuai kebutuhan. |
| 1003 | binary frames are not accepted | Frame WebSocket biner diterima; hanya frame teks UTF-8 yang diterima | Tidak | Jangan menyambungkan kembali secara otomatis. Perbarui klien untuk mengirim frame teks. |
| 1009 | message too large | Payload masuk melebihi 1 MiB | Tidak | Jangan menyambungkan kembali secara otomatis. Pecah permintaan besar atau kurangi ukuran payload. |
| 1012 | service restart | Server dimulai ulang, atau sesi mencapai masa hidup maksimum (24 jam) | Ya | Sambungkan kembali dengan backoff berjitter acak, buat ulang langganan, dan lakukan backfill data yang terlewat. |
| 1013 | chain unavailable | Chain tidak tersedia | Ya | Sambungkan kembali dengan backoff eksponensial full jitter, buat ulang langganan, dan lakukan backfill data yang terlewat. |
| 1013 | overloaded | Server kelebihan beban sementara | Ya | Sambungkan kembali dengan backoff eksponensial full jitter, buat ulang langganan, dan lakukan backfill data yang terlewat. |
| 4402 | insufficient balance | Saldo akun habis | Tidak | Jangan menyambungkan kembali secara otomatis. Top up saldo Anda, lalu sambungkan kembali. |
| 4404 | invalid api key | API key tidak dikenal, dinonaktifkan, atau dicabut | Tidak | Jangan menyambungkan kembali secara otomatis. Verifikasi atau rotasi API key di konsol sebelum menyambungkan kembali. |
| 4408 | slow consumer | Server menutup sesi yang antrean push-nya melampaui 512 KiB dan membuang notifikasi tertunda; klien mungkin tidak menerima frame penutupan (browser melaporkan 1006) | Ya | Perlakukan koneksi terputus tak terduga (tidak menerima frame penutupan, browser melaporkan 1006) seperti 4408: sambungkan kembali dengan backoff, buat ulang langganan, dan lakukan backfill data yang dibuang dengan eth_getLogs; kurangi langganan, atau baca lebih cepat. |
| 4429 | push rate exceeded | Laju notifikasi melebihi 1,000 push/detik | Ya | Kurangi langganan atau persempit filter; sambungkan kembali dengan backoff, berlangganan ulang, dan lakukan backfill. |
| 4503 | billing unavailable | Penagihan tidak tersedia sementara | Ya | Kondisi sementara; sambungkan kembali dengan backoff eksponensial full jitter. |
Penyambungan kembali dan backoff eksponensial
Untuk mencegah lonjakan penyambungan kembali serentak ketika koneksi terputus, klien harus mengimplementasikan backoff eksponensial dengan full jitter:
- Rumus backoff: Sebelum percobaan penyambungan kembali ke-n (n = 0, 1, 2, ...), tunggu durasi yang dipilih secara acak dari distribusi seragam:
delay = random(0, min(20s, 0.5s * 2^n)) - Reset penghitung: Reset penghitung percobaan ulang n menjadi 0 hanya setelah mempertahankan koneksi stabil tanpa terputus selama setidaknya
60 seconds. - Kode penutupan 1012: Tambahkan penundaan awal acak sebelum percobaan penyambungan kembali pertama untuk menghindari lonjakan penyambungan kembali serentak.
- Kode yang tidak dapat dicoba ulang: Jangan menyambungkan kembali secara otomatis pada 4402, 4404, 1003, atau 1009.
Backfill data yang terlewat setelah penyambungan kembali
Langganan WebSocket tidak bertahan lintas koneksi; notifikasi yang diterbitkan saat koneksi terputus tidak disimpan di server. Setelah tersambung kembali, klien sebaiknya menjalankan strategi mengejar ketertinggalan:
- Backfill log dengan
eth_getLogs:- Simpan secara persisten nomor blok tertinggi yang berhasil diproses (
last_processed_block). - Segera panggil
eth_subscribe("logs", ...)saat tersambung kembali untuk menangkap peristiwa langsung. - Kueri blok yang terlewat melalui
eth_getLogsdenganfromBlock: last_processed_block + 1dantoBlock: "latest"(atau blok pertama yang diterima dari aliran langsung). - Jika celah koneksi terputus melebihi
max_logs_block_rangejaringan (dariGET /v1/chains), bagi kueri menjadi potongan yang tidak melebihi batas tersebut. - Lakukan deduplikasi entri log di batas kueri menggunakan tuple unik
(blockHash, transactionHash, logIndex).
- Simpan secara persisten nomor blok tertinggi yang berhasil diproses (
- Backfill header blok dengan
eth_getBlockByNumber:- Catat nomor dan hash blok terbaru yang diterima sebelum koneksi terputus.
- Berlangganan ulang ke
newHeads. - Kueri
eth_getBlockByNumber("latest", false)dan ambil blok perantara yang terlewat secara berurutan. Verifikasi kesinambungan chain melaluiparentHashuntuk mendeteksi reorg.
Batas
| Batas | Nilai | Hasil saat terlampaui |
|---|---|---|
| Langganan per koneksi WebSocket | 100 | -32022 subscription_limit |
Langganan newHeads per koneksi WebSocket | 4 | -32022 subscription_limit |
Persyaratan filter langganan logs | Harus menentukan address atau topic0 (posisi pertama dalam topics) | -32602 logs_filter_required |
Langkah berikutnya
- Jelajahi direktori kumpulan data untuk melihat semua kumpulan data yang diindeks BlockVectra.
- Lihat paket gratis dan harga untuk memeriksa apa saja yang tercakup dalam akun Anda.
- Masuk ke konsol untuk membuat API key.
Terakhir diperbarui: