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

相关推荐
不老刘2 小时前
一行命令解决 Node.js 版本兼容问题:`--openssl-legacy-provider` 深度解析
node.js
万敏18 小时前
Vue3 全栈实战:第一阶段复盘(第1-8周)
vue.js·node.js·全栈
企业通信技术笔记20 小时前
企业IM内外网隔离部署:DNS、证书、WebSocket与跨网接口设计
websocket·网络协议·架构·php·信息与通信
濮水大叔20 小时前
舒服了,CabloyJS 的 AI Spec 驱动开发会自动生成甘特图和燃尽图
typescript·node.js·vibecoding
FungLeo21 小时前
成为全栈·Node 后端篇·部署上线:从本地起服到真正对外服务
node.js·后端部署·成为全栈
妙码生花1 天前
golang 应用服务端部署(使用 systemd 服务)
开发语言·人工智能·后端·golang·node.js·php·gin
柚稚姐姐1 天前
npm install pnpm -g npm error code EACCES npm error syscall symlink
前端·npm·node.js
Sayai1 天前
不重新打包,vim 直接改 jar 包内的前端文件:原理、步骤与避坑
前端·vim·jar
FungLeo2 天前
成为全栈·Node 后端篇·容器化:给 Node 应用写一个像样的 Dockerfile
docker·node.js·dockerfile·成为全栈·后端服务容器·docker 容器