Đăng ký WebSocket
Kết nối endpoint WebSocket của BlockVectra để eth_subscribe newHeads và logs. Tìm hiểu cách kết nối, quy tắc lọc, backoff kết nối lại và khôi phục.
BlockVectra cung cấp kết nối WebSocket bảo mật (wss://) để nhận luồng đăng ký sự kiện Ethereum thời gian thực cùng với yêu cầu JSON-RPC tiêu chuẩn.
Chọn WebSocket, Webhook hoặc thăm dò
Dùng WebSocket cho newHeads trực tiếp và logs đã lọc khi ứng dụng có thể duy trì kết nối. Dùng Blockchain Webhook API để nhận hoạt động ví được theo dõi tại endpoint HTTPS, với xác minh chữ ký body gốc, thử lại và phát lại các sự kiện khớp đã lưu giữ. Dùng thăm dò HTTP để giám sát thanh toán ERC-20 theo lịch và truy xuất bổ sung log lịch sử. Hướng dẫn stablecoin cũng trình bày bộ nhận Webhook USDT / USDC. Để so sánh kiến trúc về hỗ trợ chuỗi, yêu cầu bộ nhận và đánh đổi khi khôi phục cho nhà phát triển và AI Agent, xem hướng dẫn chọn Webhook, WebSocket hoặc thăm dò RPC.
Hỗ trợ WebSocket được xác định từ ws và subscriptions trong GET /v1/chains; hỗ trợ Push được xác định từ danh sách GET /v1/push/chains có xác thực. Chuỗi không có WebSocket vẫn có thể dùng Webhook địa chỉ nếu được liệt kê ở đó.
Ngắt kết nối WebSocket cần đăng ký lại và truy xuất bổ sung; không phát sự kiện điều khiển Push subscription.gap hay chain.reorg. Với Webhook, khoảng trống cần quét theo khoảng; thông báo tái tổ chức cần đánh dấu hoặc loại bỏ sự kiện bị thay thế trước khi giữ lại sự kiện từ chuỗi chuẩn được tự động gửi lại. Phát lại Push gửi lại các sự kiện khớp đã lưu giữ, không phải dữ liệu trước khi thêm địa chỉ hoặc chuỗi, hay khi đăng ký ở trạng thái offline. Xem quy tắc tính phí và tham chiếu lỗi khi triển khai khôi phục.
Chuỗi khả dụng
Bạn có thể kiểm tra đăng ký WebSocket có hoạt động trên một mạng hay không bằng cách đọc ws (boolean) và subscriptions (mảng loại đăng ký được hỗ trợ) trong GET /v1/chains.
Bảng dưới đây phản ánh các mạng đã bật hỗ trợ WebSocket:
| Chuỗi | Endpoint WebSocket (Key trên đường dẫn) |
|---|---|
| Robinhood Chain | wss://api.blockvectra.com/v1/robinhood_mainnet/{api_key} |
| Robinhood Chain Testnet | wss://api.blockvectra.com/v1/robinhood_testnet/{api_key} |
Kết nối và xác thực
Client thiết lập kết nối WebSocket TLS bảo mật (wss://). API key có thể được cung cấp theo hai cách:
- API key trong đường dẫn:
wss://api.blockvectra.com/v1/{chain}/{api_key} - API key trong header:
wss://api.blockvectra.com/v1/{chain}với headerx-api-key: {api_key}hoặcAuthorization: Bearer {api_key}trong handshake HTTP Upgrade.
Khi có API key trong đường dẫn, API key đó được dùng và cả hai header xác thực bị bỏ qua. Khi không có API key trong đường dẫn, x-api-key không rỗng được ưu tiên hơn Authorization: Bearer. WebSocket API của trình duyệt không thể đặt các header này; dùng URL có API key trong đường dẫn.
Kiểm tra chấp nhận handshake
Handshake có thể thất bại với:
- Xác thực: Thiếu API key trả HTTP 401 (
missing_api_key); API key không xác định, bị vô hiệu hóa hoặc thu hồi trả HTTP 401 (invalid_api_key); nếu xác thực tạm thời không khả dụng, phản hồi là HTTP 503 (auth_unavailable). - Số dư tài khoản: Tài khoản có số dư trả trước bằng không hoặc âm trả HTTP 402 (
balance_exhausted); nếu không thể xác nhận trạng thái tính phí, phản hồi là HTTP 503 (billing_unavailable). - Giới hạn kết nối: Vượt giới hạn mỗi API key (20 kết nối) hoặc mỗi tài khoản (50 kết nối) trả HTTP 429 (
ws_connection_limit). - Tính khả dụng của chuỗi: Yêu cầu chuỗi không xác định hoặc không được phục vụ trả HTTP 404 (
unknown_chain). - Dung lượng máy chủ: Khi máy chủ bận hoặc quá tải, handshake trả HTTP 503 (
overloaded) với headerRetry-After.
Sau khi kết nối, client có thể gửi yêu cầu JSON-RPC 2.0 tiêu chuẩn (như eth_blockNumber hoặc eth_call) và phương thức điều khiển đăng ký dưới dạng frame văn bản UTF-8.
Quy tắc tính phí
- Thiết lập kết nối, giữ kết nối nhàn rỗi và heartbeat ping/pong không bị tính phí.
- Lệnh gọi
eth_subscribevàeth_unsubscribethành công bị tính phí, kể cả unsubscribe trảfalse; lệnh gọi thất bại không bị tính phí. Lệnh gọi JSON-RPC thông thường tuân theo quy tắc tính phí JSON-RPC. - Thông báo
newHeadsđược tính một lần cho mỗi hash khối trên mỗi kết nối, bất kể kết nối có bao nhiêu đăng kýnewHeads. - Thông báo
logsđược tính một lần cho mỗi đăng ký, mỗi hash khối và giai đoạn có log khớp; khối không có log khớp không bị tính phí. Nhiều log khớp trong cùng khối và giai đoạn không làm tăng số lần tính phí. Các đăng ký riêng được tính riêng, kể cả khi bộ lọc chồng lấn. Log tái tổ chức (removed: true) tạo thành đơn vị riêng; khối thay thế ở cùng độ cao có hash khác và là đơn vị khác. - Thông báo chỉ bị tính phí sau khi được flush thành công vào bộ đệm gửi socket; thông báo đang xếp hàng hoặc bị bỏ mà chưa flush không bị tính phí. Thông báo xếp hàng trước phản hồi
eth_unsubscribeđược tính nếu đã flush. Thông điệp WebSocket không có HTTP header tính phí; xem mức sử dụng tài khoản để biết CU đã đo.
Phương thức đăng ký
API triển khai giao diện pub/sub Ethereum tiêu chuẩn: eth_subscribe và eth_unsubscribe.
newHeads
Phát đối tượng header khối mới mỗi khi một khối mới được thêm vào đầu chuỗi.
- Yêu cầu đăng ký:
{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]} - Phản hồi đăng ký: Trả mã định danh đăng ký thập lục phân không mang ý nghĩa có thể suy diễn:
{"jsonrpc":"2.0","id":1,"result":"0x1"} - Frame thông báo Push:
{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}
logs
Phát log sự kiện khớp tiêu chí lọc đã chỉ định.
-
Yêu cầu bộ lọc: Mọi bộ lọc đăng ký
logsphải chỉ địnhaddress(địa chỉ hợp đồng hoặc mảng địa chỉ) hoặctopic0(vị trí topic đầu tiên, không null). Bộ lọc không chỉ định cả hai (như{}hoặc{"topics":[null,"0x..."]}) bị từ chối với mã lỗi-32602(logs_filter_required). -
Giới hạn bộ lọc: Tối đa 100 địa chỉ; tối đa 4 vị trí topic với tối đa 16 hash ứng viên mỗi vị trí.
-
Dung lượng bộ lọc: Nếu bộ lọc log đang hoạt động đạt giới hạn dung lượng, đăng ký trả mã lỗi
-32022(ws_filter_capacity). -
Tái tổ chức chuỗi: Nếu khối bị loại bỏ do tái tổ chức chuỗi, thông báo log cho log bị loại bỏ có
"removed": true. -
Yêu cầu đăng ký:
{"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}
eth_unsubscribe
Chấm dứt đăng ký đang hoạt động bằng mã định danh đăng ký.
- Yêu cầu hủy đăng ký:
{"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]} - Phản hồi hủy đăng ký:
{"jsonrpc":"2.0","id":3,"result":true}
Ví dụ có thể chạy
Kết nối bằng viem v2 qua createPublicClient và transport webSocket. Thay {chain} bằng mã định danh chuỗi đích và {api_key} bằng API key của bạn:
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);
},
});Mã đóng kết nối và hành động của client
Khi máy chủ chấm dứt phiên WebSocket, nó gửi frame Close với mã đóng cụ thể và reason ngắn. Bảng dưới đây liệt kê mã đóng máy chủ phát ra và hành động được khuyến nghị:
| Mã đóng | Chuỗi reason | Mô tả | Có thể thử lại | Hành động của client |
|---|---|---|---|---|
| 1001 | idle | Kết nối không hoạt động, không có đăng ký hay thông điệp trong 3600 giây (1 giờ) | Có | Kết nối lại khi cần. |
| 1003 | binary frames are not accepted | Nhận frame WebSocket nhị phân; chỉ chấp nhận frame văn bản UTF-8 | Không | Không tự động kết nối lại. Cập nhật client để gửi frame văn bản. |
| 1009 | message too large | Payload nhận vào vượt 1 MiB | Không | Không tự động kết nối lại. Chia yêu cầu lớn hoặc giảm kích thước payload. |
| 1012 | service restart | Máy chủ khởi động lại, hoặc phiên đạt thời gian tồn tại tối đa (24 giờ) | Có | Kết nối lại với backoff có ngẫu nhiên hóa, thiết lập lại đăng ký và truy xuất bổ sung dữ liệu bị bỏ lỡ. |
| 1013 | chain unavailable | Chuỗi không khả dụng | Có | Kết nối lại với backoff cấp số nhân có full jitter, thiết lập lại đăng ký và truy xuất bổ sung dữ liệu bị bỏ lỡ. |
| 1013 | overloaded | Máy chủ tạm thời quá tải | Có | Kết nối lại với backoff cấp số nhân có full jitter, thiết lập lại đăng ký và truy xuất bổ sung dữ liệu bị bỏ lỡ. |
| 4402 | insufficient balance | Số dư tài khoản cạn | Không | Không tự động kết nối lại. Nạp thêm số dư rồi kết nối lại. |
| 4404 | invalid api key | API key không xác định, bị vô hiệu hóa hoặc thu hồi | Không | Không tự động kết nối lại. Xác minh hoặc xoay vòng API key trong bảng điều khiển trước khi kết nối lại. |
| 4408 | slow consumer | Máy chủ đóng phiên khi hàng đợi Push vượt 512 KiB và bỏ thông báo đang chờ; client có thể không nhận frame đóng (trình duyệt báo 1006) | Có | Xử lý ngắt kết nối bất ngờ (không nhận frame đóng, trình duyệt báo 1006) như 4408: kết nối lại với backoff, thiết lập lại đăng ký và truy xuất bổ sung dữ liệu bị bỏ bằng eth_getLogs; giảm số đăng ký hoặc đọc nhanh hơn. |
| 4429 | push rate exceeded | Tốc độ thông báo vượt 1,000 lượt Push/giây | Có | Giảm số đăng ký hoặc thu hẹp bộ lọc; kết nối lại với backoff, đăng ký lại và truy xuất bổ sung. |
| 4503 | billing unavailable | Tính phí tạm thời không khả dụng | Có | Trạng thái tạm thời; kết nối lại với backoff cấp số nhân có full jitter. |
Kết nối lại và backoff cấp số nhân
Để tránh nhiều client đồng loạt kết nối lại khi mất kết nối, client phải triển khai backoff cấp số nhân với full jitter:
- Công thức backoff: Trước lần thử kết nối lại thứ n (n = 0, 1, 2, ...), chờ một khoảng thời gian được chọn ngẫu nhiên đều:
delay = random(0, min(20s, 0.5s * 2^n)) - Đặt lại bộ đếm: Chỉ đặt lại bộ đếm thử lại n về 0 sau khi duy trì kết nối ổn định, không gián đoạn ít nhất
60 seconds. - Mã đóng 1012: Thêm thời gian chờ ban đầu ngẫu nhiên trước lần thử kết nối lại đầu tiên để tránh tăng đột biến do kết nối lại đồng loạt.
- Mã không thể thử lại: Không tự động kết nối lại với 4402, 4404, 1003 hoặc 1009.
Truy xuất bổ sung dữ liệu bị bỏ lỡ sau khi kết nối lại
Đăng ký WebSocket không tồn tại qua các kết nối; thông báo phát trong lúc ngắt kết nối không được lưu giữ trên máy chủ. Sau khi kết nối lại, client nên thực hiện chiến lược bắt kịp dữ liệu:
- Truy xuất bổ sung log bằng
eth_getLogs:- Lưu bền vững số khối cao nhất đã xử lý thành công (
last_processed_block). - Gọi ngay
eth_subscribe("logs", ...)khi kết nối lại để nhận sự kiện trực tiếp. - Truy vấn khối bị bỏ lỡ qua
eth_getLogsvớifromBlock: last_processed_block + 1vàtoBlock: "latest"(hoặc khối đầu tiên nhận từ luồng trực tiếp). - Nếu khoảng ngắt kết nối vượt
max_logs_block_rangecủa mạng (từGET /v1/chains), chia truy vấn thành các phần không vượt giới hạn đó. - Loại trùng mục log ở ranh giới truy vấn bằng bộ giá trị duy nhất
(blockHash, transactionHash, logIndex).
- Lưu bền vững số khối cao nhất đã xử lý thành công (
- Truy xuất bổ sung header khối bằng
eth_getBlockByNumber:- Ghi lại số khối và hash mới nhất nhận trước khi ngắt kết nối.
- Đăng ký lại
newHeads. - Truy vấn
eth_getBlockByNumber("latest", false)và lấy tuần tự các khối trung gian bị thiếu. Xác minh tính liên tục của chuỗi quaparentHashđể phát hiện tái tổ chức.
Giới hạn
| Giới hạn | Giá trị | Kết quả khi vượt |
|---|---|---|
| Đăng ký mỗi kết nối WebSocket | 100 | -32022 subscription_limit |
Đăng ký newHeads mỗi kết nối WebSocket | 4 | -32022 subscription_limit |
Yêu cầu bộ lọc đăng ký logs | Phải chỉ định address hoặc topic0 (vị trí đầu tiên trong topics) | -32602 logs_filter_required |
Các bước tiếp theo
- Duyệt danh mục bộ dữ liệu để xem mọi bộ dữ liệu BlockVectra lập chỉ mục.
- Xem gói miễn phí và bảng giá để kiểm tra những gì tài khoản của bạn bao gồm.
- Đăng nhập bảng điều khiển để tạo API key.
Cập nhật lần cuối: