Node.js中Solana WebSocket的programSubscribe如何过滤仅获取新事件?
如何过滤Solana programSubscribe WebSocket仅获取连接后的新事件?
使用Solana的JSON RPC WebSocket方法programSubscribe时,会收到早至一年前的旧事件,需要实现仅获取WebSocket连接建立后的新事件。
相关代码
const socket = 'https://api.mainnet-beta.solana.com'; socket.open(); try{ socket.onopen = () => { isWebSocketConnected(socket); try{ socket.send( JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'programSubscribe', params: [ programID, { encoding: 'jsonParsed', commitment: 'finalized', }, ], }) ) isSubscribed = true; logToLogFile("Socket", "Subscription message sent"); }catch(error){ logToLogFile("SocketError", `Subscription message failed ${error}`); } } }catch (error){ logToLogFile("SocketError", `Socket failed to open ${error}`); }
已尝试的方法
曾尝试获取最新slot并与当前slot对比,但仍有旧数据返回。
解决方案
利用Solana RPC的programSubscribe方法支持的startSlot参数,在订阅时指定连接建立时的最新finalized slot,让服务端仅推送该slot之后的新事件。
修改后的代码如下:
const socket = 'https://api.mainnet-beta.solana.com'; socket.open(); try { socket.onopen = () => { isWebSocketConnected(socket); try { // 先获取当前最新的finalized slot socket.send(JSON.stringify({ jsonrpc: '2.0', id: 2, method: 'getSlot', params: ['finalized'] })); socket.onmessage = (msg) => { const response = JSON.parse(msg.data); // 处理getSlot的响应 if (response.id === 2) { const currentFinalizedSlot = response.result; // 发送订阅请求,指定从当前slot开始接收事件 socket.send( JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'programSubscribe', params: [ programID, { encoding: 'jsonParsed', commitment: 'finalized', startSlot: currentFinalizedSlot // 关键参数:过滤旧事件 }, ], }) ); isSubscribed = true; logToLogFile("Socket", "Subscription message sent"); } else if (response.method === 'programNotification') { // 处理新的程序事件 const eventData = response.params.result; // ... 你的事件处理逻辑 } }; } catch(error) { logToLogFile("SocketError", `Subscription setup failed ${error}`); } }; } catch (error) { logToLogFile("SocketError", `Socket failed to open ${error}`); }
原理说明
startSlot参数会告诉Solana RPC服务端,仅推送该slot及之后的finalized区块中与目标程序相关的事件,从根源上过滤掉连接建立前的旧数据。- 先调用
getSlot获取当前finalized slot,确保订阅的起点是连接建立时的最新状态,避免遗漏刚发生的事件。
内容的提问来源于stack exchange,提问作者HelplessInWeb3
相关产品推荐
相关产品推荐

