跳到主要内容

BrowseCrawler

概述

BFS 队列遍历整棵 AddressSpace 子树, 双重保护 (max_depth + max_nodes)。

API

函数类别读写说明
DarraUa_BrowseCrawler_New(ua, max_depth, max_nodes, filter, &out_h)构造构造
DarraUa_BrowseCrawler_Free(h)释放析构
DarraUa_BrowseCrawler_Crawl(h, root, progress_cb, cancel_flag, &out_result)方法同步 BFS, 阻塞调用
DarraUa_FreeCrawlResult(result)释放释放结果

DarraUa_CrawlResult

typedef struct {
DarraUa_CrawlNode* nodes; // 扁平节点数组
size_t node_count;
DarraUa_KvPair* children; // 父→子列表 (序列化为 KV)
size_t children_count;
int64_t elapsed_ms;
} DarraUa_CrawlResult;

代码示例

#include <opcua.h>
#include <stdatomic.h>

void on_progress(int count, const char* nid, void* ctx) {
printf("\r已抓 %d 个, 当前 %s", count, nid);
}

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

// 1) 爬整棵 ObjectsFolder
DarraUa_BrowseCrawler* crawler;
DarraUa_BrowseCrawler_New(ua, 8, 50000, NODE_CLASS_UNSPECIFIED, &crawler);

atomic_int cancel_flag = 0;
DarraUa_CrawlResult* result = NULL;
DarraUa_BrowseCrawler_Crawl(crawler, "i=85", on_progress, &cancel_flag, NULL, &result);

printf("\n共 %zu 节点, 耗时 %lld ms\n",
result->node_count, (long long)result->elapsed_ms);

for (size_t i = 0; i < result->node_count; ++i)
printf(" %s (%s)\n", result->nodes[i].browse_name, result->nodes[i].node_id);

DarraUa_FreeCrawlResult(result);
DarraUa_BrowseCrawler_Free(crawler);

DarraUa_Session_Free(ua);
return 0;
}

性能

节点规模耗时
1,000~0.5s
10,000~5s
50,000~25s

最佳实践

  • 限定 root, 不要从 i=84 (Root) 开始
  • 用 nodeClassFilter 节省内存
  • 启动时一次性爬
  • 给用户取消按钮 (cancel_flag)

跨语言对照

C#PythonJavaC++RustC
BrowseCrawlerBrowseCrawlerBrowseCrawlerBrowseCrawlerBrowseCrawlerDarraUa_BrowseCrawler_*
CrawlAsynccrawl_asynccrawlAsyncCrawlAsynccrawl_asyncDarraUa_BrowseCrawler_Crawl

下一步