跳到主要内容

FindServers (C)

前置 / 配套

API

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Discovery_FindServers(
const char* endpoint_url,
uint32_t timeout_ms,
DarraUa_FindServersResult** out_result);

DARRA_OPCUA_API uint32_t DARRA_OPCUA_CALL
DarraUa_FindServersResult_GetCount(const DarraUa_FindServersResult* r);

DARRA_OPCUA_API const DarraUa_ApplicationDescription* DARRA_OPCUA_CALL
DarraUa_FindServersResult_GetServer(
const DarraUa_FindServersResult* r, uint32_t index);

DARRA_OPCUA_API void DARRA_OPCUA_CALL
DarraUa_FindServersResult_Delete(DarraUa_FindServersResult* r);

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

ApplicationDescription 字段

typedef struct {
char* application_uri;
char* product_uri;
char* application_name; /* LocalizedText.text */
int32_t application_type; /* 0=Server 1=Client 2=ClientAndServer 3=DiscoveryServer */
char* gateway_server_uri;
char* discovery_profile_uri;
int32_t discovery_url_count;
char** discovery_urls;
} DarraUa_ApplicationDescription;

所有指针字段由 Stack 在 FindServers 内部分配, 由 DarraUa_FindServersResult_Delete 统一释放.


完整示例

#include <darra_opcua/darra_opcua.h>
#include <stdio.h>

int main(int argc, char** argv)
{
const char* lds = (argc >= 2) ? argv[1] : "opc.tcp://lds-host:4840";
DarraUa_Initialize();

DarraUa_FindServersResult* res = NULL;
DarraUa_Status st = DarraUa_Discovery_FindServers(lds, 5000, &res);
if (!DARRA_UA_STATUS_IS_GOOD(st)) {
fprintf(stderr, "FindServers failed: 0x%08X (%s)\n",
(unsigned)st, DarraUa_StatusName(st));
DarraUa_Shutdown();
return 1;
}

uint32_t n = DarraUa_FindServersResult_GetCount(res);
printf("Domain has %u servers:\n", (unsigned)n);

for (uint32_t i = 0; i < n; ++i) {
const DarraUa_ApplicationDescription* a =
DarraUa_FindServersResult_GetServer(res, i);
if (!a) continue;
printf("\n App: %s\n", a->application_name);
printf(" AppUri: %s\n", a->application_uri);
printf(" Type: %d\n", (int)a->application_type);
printf(" URLs:\n");
for (int u = 0; u < a->discovery_url_count; ++u)
printf(" - %s\n", a->discovery_urls[u]);
}

DarraUa_FindServersResult_Delete(res);
DarraUa_Shutdown();
return 0;
}

LDS

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

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


用例: 主备 Server 切换

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

const char* primary_uri = "urn:plant:server-primary";
const char* backup_uri = "urn:plant:server-backup";

DarraUa_FindServersResult* res = NULL;
DarraUa_Discovery_FindServers("opc.tcp://lds:4840", 5000, &res);

const char* chosen_url = NULL;
uint32_t n = DarraUa_FindServersResult_GetCount(res);
for (uint32_t i = 0; i < n; ++i) {
const DarraUa_ApplicationDescription* a =
DarraUa_FindServersResult_GetServer(res, i);
if (strcmp(a->application_uri, primary_uri) == 0 &&
a->discovery_url_count > 0) {
chosen_url = a->discovery_urls[0];
break;
}
}
if (!chosen_url) {
/* 退到备 */
for (uint32_t i = 0; i < n; ++i) {
const DarraUa_ApplicationDescription* a =
DarraUa_FindServersResult_GetServer(res, i);
if (strcmp(a->application_uri, backup_uri) == 0 &&
a->discovery_url_count > 0) {
chosen_url = a->discovery_urls[0];
break;
}
}
}
/* ... 用 chosen_url 配 cfg.endpoint_url 建会话 ... */
DarraUa_FindServersResult_Delete(res);

下一步