跳到主要内容

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();
}

下一步​