跳到主要内容

BrowseNext (C)

Browse 返回的子节点超过服务端单页限制时, 服务端在 BrowseResult 里返回非空的 ContinuationPoint (续翻凭证). 用 BrowseNext 继续拿下一页.

前置阅读
  • 想拿到 ContinuationPoint 必须先 Browse, 然后调 _GetContinuationPoint, 见 Browse.
  • 想直接拿全部子节点的封装模板请看 Browse 自动分页.

API

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Session_BrowseNext(
DarraUa_SessionHandle h,
int32_t release_continuation_points, /* 1 = release, 0 = continue */
const uint8_t* continuation_point,
int32_t continuation_point_len,
DarraUa_BrowseResult** out_result);

DARRA_OPCUA_API const uint8_t* DARRA_OPCUA_CALL
DarraUa_BrowseResult_GetContinuationPoint(
const DarraUa_BrowseResult* r, int32_t* out_len);
参数说明
release_continuation_points1 = 放弃续翻, 服务端释放资源 (不返回 references)
continuation_point / _len上一次 BrowseResult 给的续翻凭证
out_result出参, 含本页 references + 新的 ContinuationPoint

_GetContinuationPoint 返回的指针指向 BrowseResult 内部缓冲, 不要 free, 且 BrowseResult_Delete 后失效. 如要保留请自行拷贝.


完整翻页例子

#include <darra_opcua/darra_opcua.h>
#include <stdio.h>
#include <string.h>

static void browse_all(DarraUa_SessionHandle h, const char* root)
{
DarraUa_BrowseResult* page = NULL;
DarraUa_Status st = DarraUa_Session_BrowseNode(
h, root, DARRA_UA_NODE_CLASS_UNSPECIFIED, &page);
if (!DARRA_UA_STATUS_IS_GOOD(st) || !page) return;

uint32_t total = 0;
char id_buf[128];

while (page) {
uint32_t n = DarraUa_BrowseResult_GetCount(page);
for (uint32_t i = 0; i < n; ++i) {
const DarraUa_ReferenceDescription* rd =
DarraUa_BrowseResult_GetReference(page, i);
DarraUa_Ref_GetNodeIdString(rd, id_buf, (int32_t)sizeof(id_buf));
printf(" %s\n", id_buf);
}
total += n;

/* 拿续翻凭证, 拷贝出来 (因为 page_Delete 会失效) */
int32_t cp_len = 0;
const uint8_t* cp = DarraUa_BrowseResult_GetContinuationPoint(page, &cp_len);
if (!cp || cp_len <= 0) {
DarraUa_BrowseResult_Delete(page);
break;
}
uint8_t cp_copy[256]; /* 服务端一般 < 64 字节 */
if (cp_len > (int32_t)sizeof(cp_copy)) {
DarraUa_BrowseResult_Delete(page);
break; /* 异常长度, 放弃 */
}
memcpy(cp_copy, cp, (size_t)cp_len);
DarraUa_BrowseResult_Delete(page);

/* 翻下一页 */
page = NULL;
DarraUa_Session_BrowseNext(
h, /*release*/ 0, cp_copy, cp_len, &page);
}

printf("Total %u children\n", (unsigned)total);
}

主动释放 (节省服务端资源)

服务端为每个 ContinuationPoint 维护状态, 占用资源. 如果中途不想继续翻, 调 release=1 显式释放:

DarraUa_Session_BrowseNext(h, /*release*/ 1, cp_copy, cp_len, NULL);

否则服务端会在超时后 (典型 5 分钟) 自动 GC.


注意

  • ContinuationPoint 是不透明字节数组, 不要修改 / 解析
  • 同一个 ContinuationPoint 只能用一次 (用完无效)
  • 服务端 ContinuationPoint 数量上限 (通常每 Session ~10-100), 超过后旧 CP 会被踢
  • 翻页期间不要 Disconnect, CP 会失效

下一步