综合

A股实时行情看板怎么做:多股票监控里,WebSocket 有消息不等于全表已更新

作者: TickDB Research · 发布: 2026/9/2 · 阅读: 8

标签: 掘金

你的看板显示五只股票,价格都在。绿色红色交替,数字在跳。你扫一眼,觉得一切正常。

直到你发现其中一只的价格已经很久没变,但你无法从页面上判断它到底是在正常波动,还是停在了某个旧快照上。

有价格≠在更新。这是多股票行情看板最容易踩的坑。


30秒抓住重点

>

问题:看板上每格都有数字,不代表每格都收到过实时消息

根因:快照写入和消息写入,在应用层被混成了同一个"正常"状态

方案:加一个state字段,把"只有快照"和"见过消息"分开

效果:看板能告诉你,每个格子的"正常"是根据什么得出的

适合:自己写行情看板、多标的监控、WebSocket订阅的人

TickDB 在这条链路里做什么:REST ticker 取行情快照,WebSocket ticker 接收订阅消息。至于某一格到底处于什么状态,由应用自己逐标的记录。下面代码解决的就是这个应用层问题。


先看代码:两个函数解决状态混用

核心就一件事:快照写入和消息更新,不能共用同一个"正常"状态。

const board = new Map();

function rowFor(symbol) {
  if (!board.has(symbol)) {
    board.set(symbol, {
      symbol,
      last_price: null,        // 来自 WebSocket 消息的最新价格
      snapshot_price: null,     // 来自 REST 快照的价格
      last_message_at: null,    // 最后收到消息的时间
      last_snapshot_at: null,   // 最后收到快照的时间
      state: "unknown",
      next_check: "waiting_for_snapshot"
    });
  }
  return board.get(symbol);
}

// REST ticker 的返回行:只证明本次拿到了快照。
function applySnapshot(row) {
  const item = rowFor(row.symbol);

  // 记录快照时间和快照价格
  item.snapshot_price = row.last_price;
  item.last_snapshot_at = new Date().toISOString();

  // 只有在尚未收到任何 WebSocket 消息时,才用快照价格填充显示价格。
  // 如果已经收到过消息,不覆盖 last_price——否则旧快照可能把更新的价格盖掉。
  if (item.state === "unknown") {
    item.last_price = row.last_price;
    item.state = "snapshot_only";
    item.next_check = "wait_for_symbol_message";
  }
}

// WebSocket ticker 已解析为 { symbol, last_price } 后再调用。
function applyTicker(ticker) {
  const item = rowFor(ticker.symbol);
  item.last_price = ticker.last_price;
  item.last_message_at = new Date().toISOString();
  item.state = "live_message_seen";
  item.next_check = "monitor_freshness";
}

applySnapshotapplyTicker 是两种完全不同的写入路径。

快照只证明"我拿到过一次结果",消息只证明"本次观察中见过该标的消息"。如果两个函数把状态都设成同一个值,看板就无法告诉你某个价格到底来自哪里。

订阅 ticker 时,按你的监控列表传入标的:

{
  "cmd": "subscribe",
  "data": {
    "channel": "ticker",
    "symbols": ["YOUR_SYMBOL_1", "YOUR_SYMBOL_2"]
  }
}

两种格子,看起来一样,实际不同

如果页面只保存最后价格,旧快照可能继续显示,而应用没有证据证明它仍在更新。这是常见的应用层风险,不是接口本身的问题。

页面上看到的内容实际证据应显示的状态
有价格,但没有该标的消息记录REST 快照已写入snapshot_only
有价格,且记录到该标的消息时间WebSocket ticker 已到达live_message_seen

看板至少要打印这五列,才能知道每个格子的"正常"是根据什么得出的:

字段用途
symbol找到对应标的
last_price当前显示价格(来自消息或快照)
last_message_at最后一次收到该标的消息的时间
state区分未知、只有快照、见过消息
next_check告诉应用下一步应等待消息还是持续监控新鲜度

TickDB 在这条链路里做什么

TickDB 提供两种可核对的输入:

  • REST ticker:一次查询一个或多个标的的行情快照
  • WebSocket ticker:订阅 ticker 消息

看板自己的职责是保存每个标的最后一次消息时间、当前状态和后续处置标记。断线后的重新订阅、快照补查、去重和陈旧告警,这些是应用层需要设计的后续动作,本次未验证恢复流程。接口连上了,不代表这些事会自动完成。


真实调用:同一张看板,两种状态

本次有限观察窗口内:

做了什么:
  REST 查询多个标的快照 → 返回价格
  WebSocket 订阅同一批标的 → 观察若干时间

看到了什么:
  两个样本中,一个见到 ticker 消息,另一个只有快照

说明了什么:
  同一张看板里的不同标的,证据状态可以不同

这次调用没有测试延迟、长期连接、全市场覆盖、断线重连或补查效果。它只证明一件事:快照和消息是两种证据,必须分开记录。


检查清单

  • [ ] REST 快照写入后,是否只把状态设为 snapshot_only
  • [ ] 每条 ticker 消息,是否只更新它对应的标的?
  • [ ] 页面是否展示或至少保存 last_message_at
  • [ ] 一旦需要恢复,是否重新确认每个标的的状态,而不是只确认连接对象还存在?

FAQ

怎么开始?

先拿自己的两三个监控标的,接入 REST 快照和 ticker 订阅,再把上面五列打印到控制台。先看状态是否符合预期,再做页面样式。

数据异常时怎么定位或补回?

不要覆盖原状态。先保留最后价格、最后消息时间和状态,再由应用决定是否重新订阅、重新取快照或标记为待核。这样复盘时能分清是没有拿到快照,还是没有看到消息。

如果我只用 REST 轮询,能省掉这个状态管理吗?

不能完全省掉。只用 REST 时,你仍然要保存 last_fetched_at、请求结果和陈旧阈值,自己判断数据是否还新鲜。区别在于不用 live_message_seen 来判断消息到达,但状态管理本身逃不掉。

重连后,旧的 live_message_seen 状态还有效吗?

无效。重连后,应用可以将每个标的暂时置为"等待本连接消息确认",待新消息到达后再回到 live_message_seen。这是建议的应用层设计,本次未实测。


把"最后价格"旁边加一个状态字段。它不会替你做交易判断,却能让你少把旧快照当成正在更新的数据。

风险提示:本文讨论行情数据接入与状态展示,不构成投资或交易建议。

通过 TickDB API 获取实时行情数据

一个 API 接入外汇、加密货币、美股、港股、A股、贵金属和全球指数的实时行情。支持 WebSocket 低延迟推送,免费开始使用。

免费领取 API Key查看 API 文档

相关文章