跳到主要内容

历史流式读

概述

C 没有 IAsyncEnumerable / Stream, SDK 用 callback 模式: 每读到一条 DataValue 调一次 callback, 业务可立即处理 (例如 push 到 chart) 而不必先装进 array。

对应规范段: Part 11 §6.5。

API

函数类别读写说明
DarraUa_Session_ReadHistoryStream(ua, nid, t0_ms, t1_ms, batch_size, on_value, ctx)历史流式读, 每条调 on_value

回调签名: int cb(const DarraUa_DataValue* dv, void* ctx) — 返回非零表示继续, 返回 0 提前退出。

t0_ms / t1_ms 是 UTC ms epoch。

代码示例

#include <opcua.h>

int on_value(const DarraUa_DataValue* dv, void* ctx) {
/* 处理每个点 */
chart_add_point(ctx, dv->source_timestamp, dv->value /* AsDouble 等 */);
return 1; // 继续
}

int main() {
DarraUa_Session* ua;
DarraUa_Session_New("opc.tcp://localhost:4840", &ua);
DarraUa_Session_Connect(ua);

int64_t t1_ms = /* now */;
int64_t t0_ms = t1_ms - 24LL * 3600 * 1000;

// 1) 边拉边渲染
DarraUa_StatusCode st = DarraUa_Session_ReadHistoryStream(ua, "ns=2;s=Temp",
t0_ms, t1_ms, /*batch_size=*/1000, on_value, my_chart);

// 2) 取消支持: callback 返回 0
int cancel_requested = 0;
auto inner_cb = ^(const DarraUa_DataValue* dv, void* ctx) -> int {
if (cancel_requested) return 0;
process(dv);
return 1;
};
DarraUa_Session_ReadHistoryStream(ua, "ns=2;s=Temp", t0_ms, t1_ms, 1000,
inner_cb, &cancel_requested);

DarraUa_Session_Free(ua);
return 0;
}

实现限制

  • 当前底层 ReadHistory 不暴露 ContinuationPoint, 一次 RPC 返回区间内所有点 (受 batch_size 限)
  • 大区间业务侧自行切片调多次
  • callback 不能阻塞超过 100 ms, 不然 RPC 队列卡

最佳实践

  • callback 内部不做长操作
  • 区间 > 1 小时建议外层切片
  • UI 渲染节流: 累积 100 条再 refresh

跨语言对照

C#PythonJavaC++RustC
ReadHistoryStreamAsyncread_history_streamreadHistoryStreamReadHistoryStreamread_history_streamDarraUa_Session_ReadHistoryStream

下一步