BrowseNext
当 Browse / BrowseWithPaging 返回的子节点超过服务端
单页限制时, 服务端会返回非空的 ContinuationPoint (续翻凭证). 用 browse_next 继续拿下一页.
前置阅读
- 想拿到 ContinuationPoint 必须用 BrowseWithPaging, 普通 Browse 会丢弃 CP.
签名
pub fn Session::browse_next(
&self,
continuation_point: &[u8],
release: bool,
) -> Result<BrowsePage, OpcUaError>;
| 参数 | 说明 |
|---|---|
continuation_point | 上一次 Browse / BrowseNext 返回的续翻凭证 |
release | true = 放弃续翻, 服务端释放资源 (不返回 references) |
BrowsePage 字段
pub struct BrowsePage {
pub references: Vec<Reference>,
/// Some(非空) 表示还有更多页, 用 browse_next 续翻.
/// None / Some(空) 表示无更多页.
pub continuation_point: Option<Vec<u8>>,
}
完整翻页例子
use darra_opcua::NodeClass;
let mut page = s.browse_with_paging("ns=2;s=BigFolder", NodeClass::Unspecified)?;
let mut all_refs = page.references.clone();
while let Some(cp) = page.continuation_point.take() {
if cp.is_empty() { break; }
page = s.browse_next(&cp, false)?;
all_refs.extend(page.references.iter().cloned());
}
println!("Total {} children", all_refs.len());
主动释放 (节省服务端资源)
服务端为每个 ContinuationPoint 维护状态, 占用资源. 如果中途不想继续翻, 调
release=true 显式释放:
s.browse_next(&cp, true)?;
否则服务端会在超时后 (典型 5 分钟) 自动 GC.
browse_all (推荐)
Session::browse_all 内部循环 browse_next 直到 ContinuationPoint 空,
最后自动 release 残留的:
pub fn browse_all(&self, node_id: &str, filter: NodeClass, max_pages: usize)
-> Result<Vec<Reference>, OpcUaError>;
max_pages— 安全上限, 防止服务端异常持续返回 CP 导致死循环- 达到
max_pages后, 把当前 CP 主动 release 掉
let all = s.browse_all("ns=2;s=BigFolder", NodeClass::Variable, 50)?;
println!("{} variables under BigFolder", all.len());
注意
ContinuationPoint是不透明字节数组, 不要修改 / 解析- 同一个
ContinuationPoint只能用一次 - 服务端
ContinuationPoint数量上限 (通常每 Session ~10-100), 超过后旧 CP 会被踢