Sử dụng WebSocket
Mục đích
Hướng dẫn kết nối real-time với HieraChain qua WebSocket protocol để nhận thông báo sự kiện (events) và khối (blocks) mới ngay khi chúng được ghi vào chuỗi.
Kết nối WebSocket
Endpoint
Với authentication (nếu bật):
Message Format
Tất cả messages là JSON.
Client → Server:
// Subscribe to all events/blocks from a chain
{"action": "subscribe", "chain_name": "supply_chain"}
// Subscribe to specific event type
{"action": "subscribe", "chain_name": "supply_chain", "event_type": "production_complete"}
// Unsubscribe
{"action": "unsubscribe", "chain_name": "supply_chain"}
// Keep-alive ping
{"action": "ping"}
Server → Client:
// New block created
{"type": "new_block", "chain_name": "supply_chain", "data": {"block_hash": "...", "height": 10}}
// New event added
{"type": "new_event", "chain_name": "supply_chain", "data": {"entity_id": "...", "event_type": "..."}}
// Pong response
{"type": "pong", "timestamp": 1234567890}
// Error
{"type": "error", "message": "Invalid subscription"}
Ví dụ: JavaScript Client
// Kết nối WebSocket
const ws = new WebSocket('ws://localhost:2661/ws');
// Xử lý khi kết nối
ws.onopen = () => {
console.log('✅ Connected to HieraChain WebSocket');
// Subscribe vào chain 'supply_chain'
ws.send(JSON.stringify({
action: 'subscribe',
chain_name: 'supply_chain'
}));
// Hoặc subscribe theo event type
ws.send(JSON.stringify({
action: 'subscribe',
chain_name: 'supply_chain',
event_type: 'production_complete'
}));
};
// Nhận message
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'new_block':
console.log('🆕 New block:', data.data.block_hash);
break;
case 'new_event':
console.log('📝 New event:', data.data.event_type);
break;
case 'pong':
console.log('💚 Pong received');
break;
case 'error':
console.error('❌ Error:', data.message);
break;
}
};
// Xử lý lỗi
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
// Xử lý đóng kết nối
ws.onclose = () => {
console.log('🔌 Disconnected');
};
// Keep-alive: gửi ping mỗi 30 giây
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ action: 'ping' }));
}
}, 30000);
Ví dụ: Python Client
import asyncio
import websockets
import json
async def listen():
uri = "ws://localhost:2661/ws"
async with websockets.connect(uri) as ws:
# Subscribe to chain
await ws.send(json.dumps({
"action": "subscribe",
"chain_name": "supply_chain"
}))
# Listen for messages
async for message in ws:
data = json.loads(message)
if data["type"] == "new_block":
print(f"🆕 New block: {data['data']['block_hash']}")
elif data["type"] == "new_event":
print(f"📝 New event: {data['data']['event_type']}")
elif data["type"] == "pong":
print("💚 Pong")
asyncio.run(listen())
Ví dụ: Rust Client (tokio-tungstenite)
use tokio_tungstenite::{connect_async, tungstenite::Message};
use futures_util::{StreamExt};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = "ws://localhost:2661/ws";
let (ws_stream, _) = connect_async(url).await?;
let (mut write, mut read) = ws_stream.split();
// Subscribe to chain
let msg = serde_json::json!({
"action": "subscribe",
"chain_name": "supply_chain"
});
write.send(Message::Text(msg.to_string())).await?;
// Listen
while let Some(msg) = read.next().await {
if let Message::Text(text) = msg? {
let data: serde_json::Value = serde_json::from_str(&text)?;
println!("Received: {:?}", data);
}
}
Ok(())
}
Connection Health
Kiểm tra số lượng kết nối:
Response:
Xử lý lỗi thường gặp
| Lỗi | Nguyên nhân | Giải pháp |
|---|---|---|
| Connection refused | Server không chạy | Chạy python -m hierachain.api.server |
| 401 Unauthorized | Thiếu token | Thêm ?token=<api_key> vào URL |
| No messages received | Chưa subscribe | Gửi message subscribe trước |
| Sudden disconnect | Server restart | Reconnect tự động trong client |