跳到主要内容

FindServers

前置 / 配套

签名​

pub fn Discovery::find_servers(
endpoint_url: &str,
timeout_ms: u32,
) -> Result<Vec<ApplicationDescription>, OpcUaError>;

向 Local Discovery Server (LDS) 查询同域内注册的所有 OPC UA Server.

ApplicationDescription 字段​

pub struct ApplicationDescription {
pub application_uri: String,
pub product_uri: String,
pub application_name: String,
pub application_type: i32, // 0=Server / 1=Client / 2=ClientAndServer / 3=DiscoveryServer
pub gateway_server_uri: String,
pub discovery_profile_uri: String,
pub discovery_urls: Vec<String>,
}
字段说明
application_uri应用 URI (全局唯一标识)
product_uri产品 URI
application_name应用显示名
application_type应用类型 (见上)
discovery_urls该 Server 的 endpoint URLs

用法​

use opcua::Discovery;

let servers = Discovery::find_servers("opc.tcp://lds-host:4840", 10_000)?;

println!("Domain has {} servers:", servers.len());
for srv in &servers {
println!("\n App: {}", srv.application_name);
println!(" AppUri: {}", srv.application_uri);
println!(" Type: {}", srv.application_type);
println!(" Discovery URLs:");
for url in &srv.discovery_urls {
println!(" - {}", url);
}
}

LDS​

LDS = Local Discovery Server, OPC Foundation 提供. 同子网内 Server 启动时可注册到 LDS, 客户端通过 FindServers 即发现全部.

LDS 默认监听 4840 (与普通 Server 同端口), 通常装在专门一台主机, 也可与 Server 共部署.

FindServersOnNetwork (扩展)​

LDS 还有 FindServersOnNetwork 服务, 跨子网通过 mDNS 发现. 当前 SDK 未暴露此 API, 如需可走底层调用.

用例: 自动 Server 切换 (冗余)​

冗余场景下, 主备 Server 都注册到同一 LDS. 客户端定期 FindServers, 主 Server 失联时切到备:

use opcua::{Discovery, Session};

let servers = Discovery::find_servers("opc.tcp://lds:4840", 10_000)?;
let primary = servers.iter().find(|s| s.application_uri == "urn:plant:server-primary");
let backup = servers.iter().find(|s| s.application_uri == "urn:plant:server-backup");

let url = primary
.and_then(|s| s.discovery_urls.first())
.or_else(|| backup.and_then(|s| s.discovery_urls.first()))
.ok_or("no server available")?
.clone();

let mut s = Session::new(&url)?;
s.connect()?;

与 GetEndpoints 的区别​

API输入输出
find_serversLDS URLServer 列表 (跨多台主机)
get_endpoints单 Server URL该 Server 的 Endpoint 列表 (单主机多组合)

通常组合用: find_servers → 拿到 Server URL → get_endpoints → 选具体 Endpoint → 连接.

错误​

StatusCode原因
BAD_COMMUNICATION_ERRORLDS 不可达
BAD_TIMEOUTtimeout_ms 超时
INVALID_ARGUMENTendpoint_url 为空 / 含 NUL
空列表LDS 上没注册任何 Server

下一步​