OrbitFlare 支持持久 WebSocket 连接,用于接收实时 Solana 数据。WebSocket 订阅在链上发生变化时主动推送更新到您的客户端——无需轮询。
WebSocket 端点使用 wss:// 协议,区域代码与 HTTP API 相同:
wss://{region}.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY
自动路由的主网端点:
wss://mainnet.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY
const WebSocket = require("ws");
const ws = new WebSocket(
"wss://mainnet.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY"
);
ws.on("open", () => {
console.log("Connected");
});
ws.on("message", (data) => {
const msg = JSON.parse(data);
console.log("Received:", msg);
});
ws.on("error", (err) => {
console.error("WebSocket error:", err);
});
ws.on("close", (code, reason) => {
console.log(`Connection closed: ${code} ${reason}`);
});
超过 60 秒没有任何消息交换的 WebSocket 连接将被服务器关闭。请发送 ping 或保持订阅活跃以维持连接。
订阅方法
accountSubscribe
当特定账户的 lamport 余额或数据发生变化时接收更新。
ws.on("open", () => {
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "accountSubscribe",
params: [
"83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri",
{ encoding: "base64", commitment: "confirmed" }
],
}));
});
更新字段:
| 字段 | 描述 |
|---|
lamports | 当前 lamport 余额 |
data | 账户数据(编码方式由 encoding 参数决定) |
owner | 所有者程序公钥 |
executable | 账户是否为可执行程序 |
rentEpoch | 下次需缴纳租金的 epoch |
logsSubscribe
实时接收交易日志消息。可选择过滤到特定程序。
// All transactions
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 2,
method: "logsSubscribe",
params: ["all"],
}));
// Filter to a specific program
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 3,
method: "logsSubscribe",
params: [
{ mentions: ["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"] }, // Raydium AMM
{ commitment: "confirmed" }
],
}));
更新字段:
| 字段 | 描述 |
|---|
signature | 交易签名(base-58 编码) |
err | 成功时为 null,失败时为错误对象 |
logs | 日志消息字符串数组 |
slotSubscribe
每次处理一个槽时接收通知。
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 4,
method: "slotSubscribe",
params: [],
}));
更新字段:
| 字段 | 描述 |
|---|
slot | 当前槽编号 |
parent | 父槽编号 |
root | 最高已确认根槽 |
signatureSubscribe
当特定交易签名达到指定确认级别时,接收一次性通知。
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 5,
method: "signatureSubscribe",
params: [
"TRANSACTION_SIGNATURE_HERE",
{ commitment: "finalized" }
],
}));
发送第一条通知后,订阅自动关闭。
programSubscribe
接收特定程序所拥有的所有账户的更新。
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 6,
method: "programSubscribe",
params: [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // SPL Token
{
encoding: "jsonParsed",
commitment: "confirmed",
filters: [{ dataSize: 165 }], // Standard token account size
}
],
}));
blockSubscribe
每个区块被确认时接收完整区块数据。需要附加功能——请联系支持团队开启。
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 7,
method: "blockSubscribe",
params: ["all", { commitment: "confirmed", encoding: "base64" }],
}));
rootSubscribe
每次最高已确认根槽推进时接收通知。
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 8,
method: "rootSubscribe",
params: [],
}));
voteSubscribe
接收在 gossip 网络中观察到的原始投票交易。数据量大——请谨慎过滤。
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 9,
method: "voteSubscribe",
params: [],
}));
取消订阅
每种订阅方法都有对应的 Unsubscribe 方法。传入初始订阅响应中返回的订阅 ID。
// Subscribe and capture the subscription ID
ws.on("message", (data) => {
const msg = JSON.parse(data);
// Subscription confirmation contains the subscription ID
if (msg.id === 1 && msg.result !== undefined) {
const subscriptionId = msg.result;
console.log("Subscribed, ID:", subscriptionId);
// Unsubscribe later
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 10,
method: "accountUnsubscribe",
params: [subscriptionId],
}));
}
});
可用的取消订阅方法:accountUnsubscribe、logsUnsubscribe、slotUnsubscribe、signatureUnsubscribe、programUnsubscribe、blockUnsubscribe、rootUnsubscribe、voteUnsubscribe。
保持连接活跃
WebSocket 连接在闲置 60 秒后将被关闭。定期发送 JSON-RPC ping 以保持连接:
const pingInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ jsonrpc: "2.0", id: 0, method: "ping" }));
}
}, 30_000);
ws.on("close", () => clearInterval(pingInterval));
重新连接
在生产应用中实现带指数退避的自动重连:
function connect(url, onMessage) {
let ws;
let delay = 1000;
let attempt = 0;
function createConnection() {
ws = new WebSocket(url);
ws.on("open", () => {
console.log("Connected (attempt", attempt + 1, ")");
delay = 1000; // reset backoff on successful connection
attempt = 0;
// re-subscribe to all channels here
});
ws.on("message", onMessage);
ws.on("close", () => {
attempt++;
const nextDelay = Math.min(delay * 2, 30_000);
console.log(`Reconnecting in ${delay}ms...`);
setTimeout(createConnection, delay);
delay = nextDelay;
});
ws.on("error", (err) => console.error("WebSocket error:", err));
}
createConnection();
return () => ws?.close();
}
const disconnect = connect(
"wss://mainnet.rpc.orbitflare.com?api_key=YOUR_LICENSE_KEY",
(data) => {
const msg = JSON.parse(data);
console.log("Update:", msg);
}
);
连接限制
WebSocket 连接与 gRPC 连接共享相同的每 IP 限制。详情请参阅认证与限制。
另请参阅