Node.js WebSocket 实现贵金属实时行情监听 伦敦金 / 伦敦银自动重连方案

摘要

贵金属回收、珠宝定价、量化监控场景中,伦敦金、伦敦银等国际贵金属行情对实时性要求高。WebSocket 长连接是最优方案,但开发中常遇到心跳缺失断连、网络波动无重连、报文解析异常等问题。本文基于 Node.js 原生 WebSocket 实现完整可部署客户端,支持多品种批量订阅,包含心跳保活、断线自动重连、异常捕获机制,数据源采用脉动行情数据 API。

关键词:Node.js;WebSocket;贵金属;伦敦金;实时行情

一、业务背景

国际贵金属价格是黄金回收门店、珠宝品牌定价、大宗贸易核算的核心参考指标,主流品种包括伦敦现货金、伦敦现货银、COMEX 黄金期货、COMEX 白银期货等。 很多项目初期用 HTTP 轮询获取行情,上线后容易出现延迟高、请求频繁触发限流等问题;改用 WebSocket 又常因为缺少生产级处理逻辑,导致连接不稳定、异常崩溃。

示例品种编码: XAU:伦敦金(现货黄金) XAG:伦敦银(现货白银) GC:COMEX 黄金期货 SI:COMEX 白银期货 通信约定:连接成功发送订阅报文,多品种逗号分隔;客户端每 10 秒发送心跳包维持链路。

二、环境依赖

javascript 复制代码
npm install ws

三、完整 WebSocket 客户端代码

javascript 复制代码
const WebSocket = require('ws');

// WebSocket服务地址,仅代码内配置
const WS_URL = 'ws://39.107.99.235/ws';
// 批量订阅贵金属品种
const SYMBOL_LIST = 'XAU,XAG,GC,SI';
// 心跳间隔 10秒
const HEARTBEAT_INTERVAL = 10000;
// 重连延迟 3秒
const RECONNECT_DELAY = 3000;

let ws = null;
let heartbeatTimer = null;

function connect() {
    ws = new WebSocket(WS_URL);

    ws.on('open', () => {
        console.log('WebSocket连接成功,批量订阅贵金属行情');
        // 发送订阅报文
        ws.send(JSON.stringify({ Key: SYMBOL_LIST }));
        // 启动心跳
        startHeartbeat();
    });

    ws.on('message', (data) => {
        try {
            const message = JSON.parse(data.toString());
            if (!message.body) return;
            const body = message.body;
            console.log('----------------------------------------');
            console.log(`品种: ${body.StockCode}`);
            console.log(`最新价: ${body.Price}  涨跌: ${body.Diff}`);
            console.log(`最高: ${body.High}  最低: ${body.Low}`);
            console.log(`更新时间: ${body.Time}`);
            console.log('----------------------------------------');
        } catch (err) {
            console.error('行情解析异常:', err.message);
        }
    });

    ws.on('close', (code, reason) => {
        console.log(`连接断开 code: ${code},${RECONNECT_DELAY}ms后自动重连`);
        stopHeartbeat();
        setTimeout(connect, RECONNECT_DELAY);
    });

    ws.on('error', (err) => {
        console.error('连接异常:', err.message);
    });
}

function startHeartbeat() {
    heartbeatTimer = setInterval(() => {
        if (ws.readyState === WebSocket.OPEN) {
            const ping = JSON.stringify({ ping: Math.floor(Date.now() / 1000) });
            ws.send(ping);
        }
    }, HEARTBEAT_INTERVAL);
}

function stopHeartbeat() {
    if (heartbeatTimer) {
        clearInterval(heartbeatTimer);
        heartbeatTimer = null;
    }
}

// 启动连接
connect();

// 优雅退出处理
process.on('SIGINT', () => {
    console.log('正在关闭连接...');
    stopHeartbeat();
    ws.close();
    process.exit(0);
});

四、HTTP 快照获取示例

不需要毫秒级推送的场景,可使用 HTTP 接口定时拉取。

javascript 复制代码
const http = require('http');

const options = {
    hostname: '39.107.99.235',
    port: 1008,
    path: '/getQuote.php?code=XAU,XAG',
    headers: {
        'Accept-Encoding': 'gzip'
    },
    timeout: 8000
};

http.get(options, (res) => {
    let data = '';
    res.on('data', (chunk) => data += chunk);
    res.on('end', () => console.log(data));
}).on('error', (err) => {
    console.error('请求失败:', err.message);
});

五、核心返回字段说明

字段 说明
StockCode 品种编码
Price 最新价格
Open 开盘价
LastClose 昨收价
High 日内最高价
Low 日内最低价
Diff 涨跌额
DiffRate 涨跌幅百分比
Time 行情更新时间

六、生产环境注意事项

  1. 必须维持 10 秒心跳,否则服务端会主动回收空闲连接;
  2. 断线重连增加延迟时间,避免网络未恢复时频繁重连;
  3. 消息解析必须增加异常捕获,防止畸形报文导致进程退出;
  4. 贵金属交易覆盖亚欧美盘,几乎全天波动,可 7×24 小时运行;
  5. 生产环境建议替换控制台输出为日志框架,行情数据落地存储。

七、总结

本方案实现贵金属多品种 WebSocket 实时监听,完整覆盖心跳保活、断线自动重连、异常捕获三大生产级能力,可直接部署用于黄金回收系统、珠宝定价平台、行情大屏等场景。修改订阅品种列表,即可快速扩展到铂金、钯金等其他贵金属品种。

相关推荐
孟陬20 分钟前
解决动态 import 类型 Any 痼癖
typescript·node.js·bun
Dumbness22 分钟前
后台管理员把自己锁在门外:RBAC 里「自己的权限只能由别人来减」
安全·node.js
攻城狮白玉3 小时前
Node.js 发布紧急安全更新:10 个漏洞,8 枚危险证书被拉黑。附AI修复提示词
node.js
Json____17 小时前
用 FastAPI + Vue3 打造一套完整的在线考试系统:从组卷到阅卷的业务闭环实践
后端·node.js·fastapi·it学习·wwwoop.com
Dumbness1 天前
写 MCP 服务器踩的坑:stdout 是协议通道,一行不带换行的日志就能让客户端超时
node.js·mcp
flash俊杰1 天前
ContentPart 联合类型实战:不碰存量消息,怎么给 ChatMessage 加图片
node.js
syagain_zsx1 天前
WebSocket 教程:websocketpp 写 echo 服务端
linux·网络·c++·websocket·网络协议·工具库
Json____1 天前
用 Node.js + Vue3 打造一个家居装修 AI 智能咨询助手
node.js·agent·网站开发·智能体·wwwoop.com
幸运小圣1 天前
fs 模块完全指南:文件读写、移动删除与文件夹操作(新手友好)【Node.js】
node.js·编辑器·vim
Dumbness2 天前
不发 npm 也能 npx:用 github: 协议分发一个零依赖 CLI
node.js