跳到主要内容

Discovery 发现

不知道服务器有哪些可用 Endpoint? 不知道局域网有哪些 OPC UA Server? 用 Discovery 服务发现.

配套阅读

GetEndpoints — 列出某个 Server 的全部 Endpoint

var endpoints = Discovery.GetEndpoints("opc.tcp://server:4840");
foreach (var ep in endpoints)
{
Console.WriteLine($"URL: {ep.EndpointUrl}");
Console.WriteLine($" SecurityMode: {ep.SecurityMode}");
Console.WriteLine($" SecurityPolicy: {ep.SecurityPolicyUri}");
Console.WriteLine($" UserTokens: {string.Join(",", ep.UserIdentityTokens.Select(t => t.TokenType))}");
}

返回的 EndpointDescription 列表通常包含:

  • 同一 URL 的 None / Sign / SignAndEncrypt 三种组合
  • 各自支持的 UserTokenType (Anonymous / Username / Certificate)

挑一个匹配你需求的, 用其 EndpointUrl + SecurityMode + SecurityPolicyUri 构造 DarraOpcUa.

FindServers — LDS 列出域内全部 Server

var servers = Discovery.FindServers("opc.tcp://lds-host:4840");
foreach (var s in servers)
{
Console.WriteLine($"App: {s.ApplicationName}");
Console.WriteLine($" AppUri: {s.ApplicationUri}");
Console.WriteLine($" ProductUri: {s.ProductUri}");
foreach (var url in s.DiscoveryUrls)
Console.WriteLine($" Discovery: {url}");
}

LDS = Local Discovery Server, OPC Foundation 提供, 同子网内 Server 可注册到 LDS, FindServers 即发现全部.

Cancel — 取消未完成的请求

某些请求 (大批量 Read / 慢 Browse) 可能阻塞太久, 可以提前取消:

uint reqHandle = ua.GetCurrentRequestHandle();  // SDK 维护
// 在另一个线程
uint cancelled = ua.Cancel(reqHandle);
Console.WriteLine($"Cancelled {cancelled} requests");

常见用法

// 1. 不加密快速试探 — 拿到 Server 信息后再决定
var endpoints = Discovery.GetEndpoints("opc.tcp://server:4840");
var ep = endpoints.First(e => e.SecurityMode == MessageSecurityMode.SignAndEncrypt);

// 2. 用挑出来的 Endpoint 真正连接
using var ua = new DarraOpcUa(
endpointUrl: ep.EndpointUrl,
securityMode: ep.SecurityMode,
securityPolicyUri: ep.SecurityPolicyUri,
clientCertificatePfxPath: "client.pfx",
clientCertificatePassword: "123456",
serverCertificatePath: null, // TOFU
username: null, password: null);
ua.Connect();

相关链接