无法获取第三方站点WebSocket全部消息的技术问询
解决WebSocket无法获取
type: data消息的问题 你的猜测完全正确——必须先发送特定的握手和订阅消息,才能拿到type: data的业务内容。这个WebSocket采用的是graphql-ws协议,并非普通WebSocket,需要严格遵循它的交互流程:
核心问题
你当前的代码仅完成了WebSocket连接建立,但没有执行graphql-ws要求的初始化握手,也未发送数据订阅请求,因此服务端只会推送心跳(type: ka),不会返回业务数据。
解决步骤及修改后代码
需要在连接打开后,先发送初始化消息,待服务端确认后,再发送对应的订阅请求:
const WebSocket = require('ws'); const ws = new WebSocket('wss://polkadot.polkastats.io/graphql', 'graphql-ws', { origin: 'https://polkastats.io' }); // 替换为从站点DevTools中抓取的真实GraphQL订阅语句 const SUBSCRIPTION_QUERY = ` subscription TargetDataSubscription { # 这里填写你需要获取的具体字段,和站点前端请求保持一致 blockUpdates { number timestamp validator } } `; ws.on('open', () => { console.log('连接已打开'); // 第一步:发送graphql-ws初始化消息 ws.send(JSON.stringify({ type: 'connection_init', payload: {} // 部分服务需要携带headers,当前站点无需额外参数 })); }); ws.on('message', (message) => { const data = JSON.parse(message); console.log('收到消息:', data); switch(data.type) { case 'connection_ack': // 第二步:初始化确认后,发送订阅请求 ws.send(JSON.stringify({ id: '1', // 自定义唯一ID,服务端会通过该ID关联后续data消息 type: 'subscribe', payload: { query: SUBSCRIPTION_QUERY, operationName: 'TargetDataSubscription' } })); break; case 'data': // 处理业务数据 console.log('业务数据:', data.payload.data); break; case 'ka': // 回复心跳,避免连接被服务端主动断开 ws.send(JSON.stringify({type: 'pong'})); break; case 'error': console.error('服务端错误:', data.payload); break; } }); ws.on('close', (code) => console.log('连接关闭,代码:', code)); ws.on('error', (err) => console.error('连接错误:', err));
关键注意事项
- 获取真实订阅语句:打开DevTools的Network面板,找到WebSocket的消息记录,复制前端发送的
subscribe类型消息中的query和operationName,替换代码中对应的内容。 - 严格遵循协议流程:必须先发送
connection_init,收到服务端返回的connection_ack后再发送订阅请求,服务端才会推送data类型的业务消息。 - 心跳维护:服务端发送
ka(保活)消息时,建议回复pong,防止连接被服务端判定为闲置而断开。
内容的提问来源于stack exchange,提问作者Serj
相关产品推荐
相关产品推荐

