跳到主要内容

历史流式读

概述

IDE 趋势图拉历史时, 一次性把万点装进 std::vector 会让进程卡顿 + OOM。ReadHistoryStream 用 callback / coroutine 模式, 业务侧拿一条处理一条。

对应规范段: Part 11 §6.5。

API

方法类别读写说明
ua.ReadHistoryStream(nodeId, t0, t1, batch_size, on_value)历史异步流式读, 每条调一次 callback

代码示例

#include <darra/opcua.h>
using namespace darra::opcua;
using namespace std::chrono;

DarraOpcUa ua("opc.tcp://localhost:4840");
ua.Connect();

auto t1 = system_clock::now();
auto t0 = t1 - hours(24);

// 1) 边拉边渲染
ua.ReadHistoryStream("ns=2;s=Temp", t0, t1, /*batch_size=*/1000,
[&](const DataValue& dv) {
chartSeries->AddPoint(dv.source_timestamp, dv.value.AsDouble());
});

// 2) 取消支持 (返回 false 提前退出)
ua.ReadHistoryStream("ns=2;s=Temp", t0, t1, 1000,
[&](const DataValue& dv) -> bool {
if (cancel_requested.load()) return false;
Process(dv);
return true;
});

// 3) 计数坏值
size_t bad = 0;
ua.ReadHistoryStream("ns=2;s=Temp", t0, t1, 1000,
[&](const DataValue& dv) {
if (dv.status != StatusCode::Good) ++bad;
});
std::cout << "24h 内 " << bad << " 个坏值\n";

实现限制

  • 当前底层 ReadHistory 不暴露 ContinuationPoint, 一次 RPC 返回区间内所有点 (受 batch_size 限)
  • 大区间业务侧自行切片
  • callback 返回 false 立即退出

最佳实践

  • callback 内部不要做长操作 (>10 ms), 不然阻塞读取
  • 区间 > 1 小时建议外层切片
  • UI 渲染节流: 累积 100 条再 refresh

跨语言对照

C#PythonJavaC++RustC
ReadHistoryStreamAsyncread_history_streamreadHistoryStreamReadHistoryStreamread_history_streamDarraUa_Session_ReadHistoryStream

下一步