การติดตามผ่าน WebSocket
เชื่อมต่อกับ WebSocket endpoint ของ BlockVectra สำหรับ eth_subscribe newHeads และ logs เรียนรู้วิธีการเชื่อมต่อ, กฎของตัวกรอง, การหน่วงเวลาเชื่อมต่อใหม่ และการกู้คืนข้อมูล
BlockVectra ให้บริการการเชื่อมต่อ WebSocket ที่ปลอดภัย (wss://) สำหรับสตรีมการติดตามเหตุการณ์ Ethereum แบบเรียลไทม์ควบคู่ไปกับคำขอ JSON-RPC มาตรฐาน
Choose WebSocket, Webhook or polling
ใช้ WebSocket สำหรับ newHeads สดและ logs ที่กรองแล้วเมื่อแอปพลิเคชันของคุณสามารถรักษาการเชื่อมต่อไว้ได้ ใช้ Blockchain Webhook API เพื่อรับกิจกรรมของกระเป๋าเงินที่ติดตาม ณ HTTPS endpoint พร้อม การตรวจสอบลายเซ็น raw-body, การลองใหม่ และการ replay ข้อมูลที่ตรงกันซึ่งเก็บรักษาไว้ ใช้ การโพลล์ HTTP สำหรับการตรวจสอบการชำระเงิน ERC-20 ตามกำหนดเวลาและการดึงข้อมูล log ย้อนหลัง คู่มือสเตเบิลคอยน์ยังแสดง ตัวรับ Webhook สำหรับ USDT / USDC ด้วย สำหรับการเปรียบเทียบเชิงสถาปัตยกรรมข้ามการรองรับของเชน ข้อกำหนดของตัวรับ และข้อดีข้อเสียในการกู้คืนสำหรับนักพัฒนาและ AI Agent โปรดดู คู่มือการเลือกระหว่าง Webhook, WebSocket หรือการโพลล์ RPC
การรองรับ WebSocket มาจาก ws และ subscriptions ใน GET /v1/chains; การรองรับ Push มาจากรายการ GET /v1/push/chains ที่ผ่านการยืนยันตัวตนแล้ว เชนที่ไม่มี WebSocket ยังคงสามารถใช้ Webhook สำหรับแอดเดรสได้หากมีรายชื่ออยู่ที่นั่น
การหลุดการเชื่อมต่อของ WebSocket กำหนดให้ต้องสมัครรับข้อมูลใหม่และดึงข้อมูลย้อนหลัง; โดยจะไม่ส่งเหตุการณ์ควบคุมของ Push อย่าง subscription.gap หรือ chain.reorg ออกมา สำหรับ Webhook ช่องว่างจะต้องสแกนตามช่วง; การแจ้งเตือน reorg กำหนดให้ต้องทำเครื่องหมายหรือละทิ้งเหตุการณ์ที่ถูกแทนที่ก่อนเก็บเหตุการณ์ canonical ที่ส่งซ้ำโดยอัตโนมัติ Push replay จะส่งซ้ำเฉพาะข้อมูลที่ตรงกันซึ่งเก็บรักษาไว้ ไม่รวมข้อมูลก่อนที่จะเพิ่มแอดเดรสหรือเชน หรือในขณะที่การติดตามอยู่ในสถานะ offline โปรดตรวจสอบ กฎการเรียกเก็บเงิน และ เอกสารอ้างอิงข้อผิดพลาด เมื่อนำการกู้คืนไปใช้งาน
Available chains
คุณสามารถตรวจสอบว่าการติดตามผ่าน WebSocket เปิดใช้งานบนเครือข่ายหรือไม่ โดยการอ่าน ws (boolean) และ subscriptions (อาร์เรย์ของประเภทที่รองรับ) ใน GET /v1/chains
ตารางด้านล่างแสดงเครือข่ายที่เปิดใช้งานการรองรับ WebSocket:
| เชน | เอนด์พอยต์ WebSocket (คีย์ในพาธ) |
|---|---|
| Robinhood Chain | wss://api.blockvectra.com/v1/robinhood_mainnet/{api_key} |
| Robinhood Chain Testnet | wss://api.blockvectra.com/v1/robinhood_testnet/{api_key} |
Connection and authentication
ไคลเอนต์สร้างการเชื่อมต่อ WebSocket ด้วย TLS ที่ปลอดภัย (wss://) โดยสามารถระบุ API key ได้สองวิธี:
- Path key:
wss://api.blockvectra.com/v1/{chain}/{api_key} - Header key:
wss://api.blockvectra.com/v1/{chain}พร้อมส่วนหัวx-api-key: {api_key}หรือAuthorization: Bearer {api_key}ในระหว่างการแฮนด์เชก HTTP Upgrade
เมื่อใช้คีย์ในพาธ ระบบจะใช้คีย์ในพาธและละเว้นส่วนหัวการยืนยันตัวตนทั้งสองรายการ หากไม่มีคีย์ในพาธ ค่า x-api-key ที่ไม่ว่างจะมีลำดับความสำคัญสูงกว่า Authorization: Bearer WebSocket API ของเบราว์เซอร์ไม่สามารถกำหนดส่วนหัวเหล่านี้ได้; ให้ใช้ URL แบบคีย์ในพาธ
Handshake admission checks
การแฮนด์เชกอาจล้มเหลวด้วยสาเหตุต่อไปนี้:
- Authentication: การไม่ระบุ API key จะส่งกลับ HTTP 401 (
missing_api_key); API key ที่ไม่รู้จัก ปิดใช้งาน หรือถูกเพิกถอน จะส่งกลับ HTTP 401 (invalid_api_key); หากระบบยืนยันตัวตนไม่พร้อมใช้งานชั่วคราว การตอบกลับจะเป็น HTTP 503 (auth_unavailable) - Account balance: บัญชีที่มียอดคงเหลือแบบชำระล่วงหน้าเป็นศูนย์หรือติดลบจะส่งกลับ HTTP 402 (
balance_exhausted); หากไม่สามารถยืนยันสถานะการเรียกเก็บเงินได้ การตอบกลับจะเป็น HTTP 503 (billing_unavailable) - Connection limits: การเชื่อมต่อเกินขีดจำกัดต่อคีย์ (20 การเชื่อมต่อ) หรือขีดจำกัดต่อบัญชี (50 การเชื่อมต่อ) จะส่งกลับ HTTP 429 (
ws_connection_limit) - Chain availability: การขอเชนที่ไม่รู้จักหรือไม่ให้บริการจะส่งกลับ HTTP 404 (
unknown_chain) - Server capacity: เมื่อเซิร์ฟเวอร์ไม่ว่างหรือโอเวอร์โหลด การแฮนด์เชกจะส่งกลับ HTTP 503 (
overloaded) พร้อมส่วนหัวRetry-After
เมื่อเชื่อมต่อแล้ว ไคลเอนต์สามารถส่งคำขอ JSON-RPC 2.0 มาตรฐาน (เช่น eth_blockNumber หรือ eth_call) และเมธอดควบคุมการติดตามในรูปแบบ text frame เข้ารหัส UTF-8 ได้
Billing rules
- การสร้างการเชื่อมต่อ, การเปิดการเชื่อมต่อทิ้งไว้โดยไม่มีกิจกรรม และ ping/pong heartbeat ไม่คิดค่าบริการ
- การเรียก
eth_subscribeและeth_unsubscribeที่สำเร็จจะคิดค่าบริการ รวมถึงการยกเลิกการติดตามที่ส่งกลับfalse; การเรียกที่ล้มเหลวจะไม่คิดค่าบริการ การเรียก JSON-RPC ทั่วไปเป็นไปตาม กฎการเรียกเก็บเงินของ JSON-RPC - การแจ้งเตือน
newHeadsจะนับหนึ่งครั้งต่อแฮชบล็อกต่อการเชื่อมต่อ โดยไม่คำนึงว่าการเชื่อมต่อนั้นจะมีการติดตามnewHeadsกี่รายการ - การแจ้งเตือน
logsจะนับหนึ่งครั้งต่อการติดตามต่อแฮชบล็อกและเฟสที่มี log ที่ตรงกัน; บล็อกที่ไม่มีข้อมูลตรงกันจะไม่คิดค่าบริการ log ที่ตรงกันหลายรายการในบล็อกและเฟสเดียวกันจะไม่เพิ่มทวีคูณค่าบริการ การติดตามที่แยกจากกันจะนับแยกกัน แม้ว่าตัวกรองจะซ้อนทับกันก็ตาม log การ Reorganize (removed: true) จะถือเป็นหน่วยแยกต่างหาก; บล็อกที่เข้ามาแทนที่ ณ ความสูงเดียวกันจะมีแฮชที่ต่างกันและถือเป็นคนละหน่วย - การแจ้งเตือนจะคิดค่าบริการหลังจากถูก flush ไปยัง socket send buffer สำเร็จแล้วเท่านั้น; การแจ้งเตือนที่อยู่ในคิวหรือตกหล่นซึ่งไม่ได้ถูก flush จะไม่คิดค่าบริการ การแจ้งเตือนที่อยู่ในคิวก่อนการตอบกลับ
eth_unsubscribeจะนับหากถูก flush ข้อความ WebSocket ไม่มีส่วนหัวการเรียกเก็บเงินของ HTTP; ตรวจสอบการใช้งานบัญชีสำหรับ CU ที่วัดปริมาณแล้ว
Subscription methods
API ใช้อินเทอร์เฟซ pub/sub มาตรฐานของ Ethereum: eth_subscribe และ eth_unsubscribe
newHeads
ส่งออบเจกต์ส่วนหัวบล็อกใหม่เมื่อใดก็ตามที่มีบล็อกใหม่ถูกเพิ่มต่อท้าย head ของเชน
- Subscribe request:
{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]} - Subscribe response: ส่งกลับตัวระบุการติดตามเลขฐานสิบหกที่ไม่เปิดเผยโครงสร้างภายใน:
{"jsonrpc":"2.0","id":1,"result":"0x1"} - Push notification frame:
{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}
logs
ส่งเหตุการณ์ log ที่ตรงกับเกณฑ์ตัวกรองที่ระบุ
-
Filter requirement: ตัวกรองการติดตาม
logsทุกรายการต้องระบุaddress(แอดเดรสของสัญญาหรืออาร์เรย์ของแอดเดรส) หรือtopic0(ตำแหน่ง topic แรก ที่ไม่ใช่ null) ตัวกรองที่ไม่ระบุทั้งสองอย่าง (เช่น{}หรือ{"topics":[null,"0x..."]}) จะถูกปฏิเสธด้วยรหัสข้อผิดพลาด-32602(logs_filter_required) -
Filter limits: สูงสุด 100 แอดเดรส; สูงสุด 4 ตำแหน่ง topic โดยมีแฮชตัวเลือกได้สูงสุด 16 รายการต่อตำแหน่ง
-
Filter capacity: หากตัวกรอง log ที่ใช้งานอยู่เต็มความจุ การติดตามจะส่งกลับรหัสข้อผิดพลาด
-32022(ws_filter_capacity) -
Chain reorganizations: หากบล็อกถูกลบออกเนื่องจาก reorg ของเชน การแจ้งเตือน log สำหรับ log ที่ถูกลบออกจะมี
"removed": true -
Subscribe request:
{"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}
eth_unsubscribe
ยกเลิกการติดตามที่ใช้งานอยู่โดยใช้ตัวระบุการติดตาม
- Unsubscribe request:
{"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]} - Unsubscribe response:
{"jsonrpc":"2.0","id":3,"result":true}
Runnable examples
เชื่อมต่อโดยใช้ viem v2 ผ่าน createPublicClient และ transport webSocket แทนที่ {chain} ด้วยตัวระบุเชนเป้าหมาย และแทนที่ {api_key} ด้วย API key ของคุณ:
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);
},
});Close codes and client actions
เมื่อเซิร์ฟเวอร์ยุติเซสชัน WebSocket จะส่งเฟรม Close พร้อมรหัสปิดเฉพาะและเหตุผลสั้นๆ ตารางด้านล่างแสดงรหัสปิดที่ส่งออกมาจากเซิร์ฟเวอร์และการดำเนินการที่แนะนำ:
| Close code | Reason string | Description | Retryable | Client action |
|---|---|---|---|---|
| 1001 | idle | การเชื่อมต่อที่ไม่มีกิจกรรมโดยไม่มีการติดตามหรือข้อความเป็นเวลา 3600 วินาที (1 ชั่วโมง) | Yes | เชื่อมต่อใหม่ตามต้องการ |
| 1003 | binary frames are not accepted | ได้รับเฟรม WebSocket ไบนารี; รองรับเฉพาะเฟรมข้อความ UTF-8 เท่านั้น | No | อย่าเชื่อมต่อใหม่อัตโนมัติ อัปเดตไคลเอนต์ให้ส่งเฟรมข้อความ |
| 1009 | message too large | เพย์โหลดขาเข้าเกิน 1 MiB | No | อย่าเชื่อมต่อใหม่อัตโนมัติ แบ่งคำขอขนาดใหญ่ออกหรือลดขนาดเพย์โหลด |
| 1012 | service restart | เซิร์ฟเวอร์กำลังรีสตาร์ต หรือเซสชันมีอายุการใช้งานถึงขีดจำกัดสูงสุด (24 ชั่วโมง) | Yes | เชื่อมต่อใหม่โดยใช้การหน่วงเวลาแบบสุ่ม สร้างการติดตามใหม่อีกครั้ง และดึงข้อมูลที่พลาดไปย้อนหลัง |
| 1013 | chain unavailable | เชนไม่พร้อมใช้งาน | Yes | เชื่อมต่อใหม่โดยใช้ full-jitter exponential backoff สร้างการติดตามใหม่อีกครั้ง และดึงข้อมูลที่พลาดไปย้อนหลัง |
| 1013 | overloaded | เซิร์ฟเวอร์โอเวอร์โหลดชั่วคราว | Yes | เชื่อมต่อใหม่โดยใช้ full-jitter exponential backoff สร้างการติดตามใหม่อีกครั้ง และดึงข้อมูลที่พลาดไปย้อนหลัง |
| 4402 | insufficient balance | ยอดคงเหลือในบัญชีหมด | No | อย่าเชื่อมต่อใหม่อัตโนมัติ เติมเงินในยอดคงเหลือของคุณ แล้วเชื่อมต่อใหม่ |
| 4404 | invalid api key | API key ไม่รู้จัก ปิดใช้งาน หรือถูกเพิกถอน | No | อย่าเชื่อมต่อใหม่อัตโนมัติ ตรวจสอบหรือสลับ API key ในคอนโซลก่อนเชื่อมต่อใหม่ |
| 4408 | slow consumer | เซิร์ฟเวอร์ปิดเซสชันที่คิวการ push เกิน 512 KiB และทิ้งการแจ้งเตือนที่รอดำเนินการ; ไคลเอนต์อาจไม่ได้รับ close frame (เบราว์เซอร์รายงาน 1006) | Yes | ปฏิบัติต่อการหลุดการเชื่อมต่อที่ไม่คาดคิด (ไม่ได้รับ close frame เบราว์เซอร์รายงาน 1006) เช่นเดียวกับ 4408: เชื่อมต่อใหม่ด้วย backoff สร้างการติดตามใหม่อีกครั้ง และดึงข้อมูลที่ตกหล่นย้อนหลังด้วย eth_getLogs; สมัครรับข้อมูลน้อยลง หรืออ่านให้เร็วขึ้น |
| 4429 | push rate exceeded | อัตราการแจ้งเตือนเกิน 1,000 push/วินาที | Yes | ลดการติดตามหรือจำกัดตัวกรองให้แคบลง; เชื่อมต่อใหม่ด้วย backoff สมัครรับข้อมูลใหม่ และดึงข้อมูลย้อนหลัง |
| 4503 | billing unavailable | ระบบการเรียกเก็บเงินไม่พร้อมใช้งานชั่วคราว | Yes | สถานะชั่วคราว; เชื่อมต่อใหม่โดยใช้ full-jitter exponential backoff |
Reconnection and exponential backoff
เพื่อป้องกันปัญหาพายุการเชื่อมต่อใหม่พร้อมกันเมื่อการเชื่อมต่อหลุด ไคลเอนต์ต้องนำ exponential backoff พร้อม full jitter ไปใช้งาน:
- สูตร Backoff: ก่อนความพยายามในการเชื่อมต่อใหม่ครั้งที่ n (n = 0, 1, 2, ...), ให้รอเป็นระยะเวลาที่สุ่มเลือกแบบสม่ำเสมอ:
delay = random(0, min(20s, 0.5s * 2^n)) - รีเซ็ตตัวนับ: รีเซ็ตตัวนับการลองใหม่ n เป็น 0 หลังจากรักษาการเชื่อมต่อที่เสถียรและไม่หยุดชะงักได้อย่างน้อย
60 วินาทีเท่านั้น - Close code 1012: หน่วงเวลาเริ่มต้นแบบสุ่มก่อนความพยายามเชื่อมต่อใหม่ครั้งแรกเพื่อหลีกเลี่ยงสไปก์การเชื่อมต่อใหม่พร้อมกัน
- รหัสที่ไม่สามารถลองใหม่ได้: อย่าเชื่อมต่อใหม่อัตโนมัติสำหรับ 4402, 4404, 1003 หรือ 1009
Backfilling missed data after reconnection
การติดตามผ่าน WebSocket จะไม่คงอยู่ข้ามการเชื่อมต่อ; การแจ้งเตือนที่ส่งออกมาระหว่างที่หลุดการเชื่อมต่อจะไม่ถูกเก็บรักษาไว้บนเซิร์ฟเวอร์ หลังจากการเชื่อมต่อใหม่ ไคลเอนต์ควรดำเนินกลยุทธ์การไล่ตามข้อมูล:
- ดึงข้อมูล log ย้อนหลังด้วย
eth_getLogs:- บันทึกหมายเลขบล็อกสูงสุดที่ประมวลผลสำเร็จไว้อย่างถาวร (
last_processed_block) - เรียก
eth_subscribe("logs", ...)ทันทีเมื่อเชื่อมต่อใหม่เพื่อจับเหตุการณ์สด - คิวรีบล็อกที่พลาดไปผ่าน
eth_getLogsด้วยfromBlock: last_processed_block + 1และtoBlock: "latest"(หรือบล็อกแรกที่ได้รับจากสตรีมสด) - หากช่องว่างการหลุดการเชื่อมต่อเกิน
max_logs_block_rangeของเครือข่าย (จากGET /v1/chains) ให้แบ่งการคิวรีออกเป็น chunk โดยไม่เกินขีดจำกัดนั้น - ขจัดข้อมูล log ที่ซ้ำกันข้ามขอบเขตการคิวรีโดยใช้ทูเพิลเฉพาะ
(blockHash, transactionHash, logIndex)
- บันทึกหมายเลขบล็อกสูงสุดที่ประมวลผลสำเร็จไว้อย่างถาวร (
- ดึงข้อมูลส่วนหัวบล็อกย้อนหลังด้วย
eth_getBlockByNumber:- บันทึกหมายเลขบล็อกและแฮชล่าสุดที่ได้รับก่อนหลุดการเชื่อมต่อ
- สมัครรับข้อมูล
newHeadsใหม่อีกครั้ง - คิวรี
eth_getBlockByNumber("latest", false)และดึงข้อมูลบล็อกระดับกลางที่ขาดหายไปตามลำดับ ตรวจสอบความต่อเนื่องของเชนparentHashเพื่อตรวจจับ reorg
Limits
| Limit | Value | Result when exceeded |
|---|---|---|
| การติดตามต่อการเชื่อมต่อ WebSocket | 100 | -32022 subscription_limit |
การติดตาม newHeads ต่อการเชื่อมต่อ WebSocket | 4 | -32022 subscription_limit |
ข้อกำหนดตัวกรองการติดตาม logs | ต้องระบุ address หรือ topic0 (ตำแหน่งแรกใน topics) | -32602 logs_filter_required |
ขั้นตอนถัดไป
- เลือกดูสารบบชุดข้อมูล เพื่อดูทุกชุดข้อมูลที่ BlockVectra ทำดัชนี
- ดูแผนบริการฟรีและราคา เพื่อตรวจสอบสิ่งที่บัญชีของคุณได้รับ
- เข้าสู่ระบบคอนโซล เพื่อสร้าง API key
อัปเดตล่าสุด: