Discovery 发现
Discovery 是无状态结构 (impl 关联函数), 不需要 Session 即可调用. 用于"连接前先探测":
子页跳转
- 列出某 Server 全部 Endpoint 请参考 GetEndpoints.
- 通过 LDS 列出域内全部 Server 请参考 FindServers.
用法模式
use darra_opcua::{Discovery, MessageSecurityMode, UserTokenType, Session, ConnectionConfig};
// 1. 先 GetEndpoints 看服务端支持哪些组合
let endpoints = Discovery::get_endpoints("opc.tcp://server:4840", 10_000)?;
// 2. 挑一个匹配的 (例如 SignAndEncrypt + Username)
let ep = endpoints.iter().find(|e| {
e.security_mode == MessageSecurityMode::SignAndEncrypt
&& e.user_tokens.iter().any(|t| t.token_type == UserTokenType::Username)
}).ok_or("no matching endpoint")?;
// 3. 用挑出来的 Endpoint 真正连接
let mut cfg = ConnectionConfig::new(&ep.endpoint_url);
cfg.security_mode = ep.security_mode;
cfg.security_policy_uri = Some(ep.security_policy_uri.clone());
cfg.username = Some("operator".into());
cfg.password = Some("secret".into());
cfg.client_cert_path = Some("client.pfx".into());
let mut s = Session::with_config(cfg)?;
s.connect()?;
内部行为
Discovery::get_endpoints / find_servers 内部:
- 进程级单例
initialize()(idempotent) - 不需要 Session, 直接对 endpoint URL 发 OPN(None) → 服务请求 → CLO
- 用 RAII guard 保证错误路径下 native result 也释放
不会 Shutdown Stack, 让 Session 后续仍可用.