跳到主要内容

FindServers

前置 / 配套

签名

namespace darra::opcua {
class Discovery {
public:
static std::vector<ApplicationDescription> FindServers(std::string const& discovery_url);
};
}

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

ApplicationDescription 字段

struct ApplicationDescription {
std::string application_uri;
std::string product_uri;
std::string application_name;
int application_type; // 0 Server / 1 Client / 2 ClientAndServer / 3 DiscoveryServer
std::string gateway_server_uri;
std::string discovery_profile_uri;
std::vector<std::string> discovery_urls;
};
字段类型说明
application_uristd::string应用 URI (全局唯一标识)
product_uristd::string产品 URI
application_namestd::string应用显示名
application_typeintServer (0) / Client (1) / ClientAndServer (2) / DiscoveryServer (3)
gateway_server_uristd::string网关 (可空)
discovery_profile_uristd::stringDiscovery Profile
discovery_urlsstd::vector<std::string>该 Server 的 endpoint URLs

用法

auto servers = Discovery::FindServers("opc.tcp://lds-host:4840");

std::cout << "Domain has " << servers.size() << " servers:\n";
for (auto const& s : servers) {
std::cout << "\n App: " << s.application_name
<< "\n AppUri: " << s.application_uri
<< "\n Type: " << s.application_type
<< "\n Discovery URLs:\n";
for (auto const& url : s.discovery_urls) {
std::cout << " - " << url << "\n";
}
}

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 失联时切到备:

auto servers = Discovery::FindServers("opc.tcp://lds:4840");

ApplicationDescription const* primary = nullptr;
ApplicationDescription const* backup = nullptr;
for (auto const& s : servers) {
if (s.application_uri == "urn:plant:server-primary") primary = &s;
if (s.application_uri == "urn:plant:server-backup") backup = &s;
}

std::string url;
if (primary && !primary->discovery_urls.empty()) {
url = primary->discovery_urls.front();
} else if (backup && !backup->discovery_urls.empty()) {
url = backup->discovery_urls.front();
}

下一步