跳到主要内容

Connect / Disconnect (C)

前置阅读

DarraUa_Session_Connect

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL
DarraUa_Session_Connect(DarraUa_SessionHandle h);

建立到 endpoint 的连接. 内部串行执行:

  1. Hello — 协商 BufferSize / MaxMessageSize
  2. OpenSecureChannel — 协商加密通道 (None / Sign / SignAndEncrypt)
  3. GetEndpoints — 拉取服务端 Endpoint 列表 (用于校验)
  4. CreateSession — 创建会话, 协商 SessionTimeout
  5. ActivateSession — 用 UserToken 激活
  6. 加载 NamespaceArray (i=2255)
  7. 自动启 KeepAlive 心跳 (keepalive_interval_ms > 0 时)

成功后:

  • DarraUa_Session_GetState(h) == DARRA_UA_SESSION_CONNECTED
返回含义
DARRA_UA_STATUS_GOOD全部步骤成功
DARRA_UA_STATUS_BAD_TIMEOUT任一阶段超时 (connect_timeout_ms)
DARRA_UA_STATUS_BAD_COMMUNICATION_ERRORTCP 连接失败 / 网络不可达
DARRA_UA_STATUS_BAD_CERTIFICATE_INVALID证书加载或校验失败
DARRA_UA_STATUS_BAD_IDENTITY_TOKEN_REJECTED用户名 / 密码错
DARRA_UA_STATUS_BAD_SECURITY_CHECKS_FAILED加密 / 签名校验失败
DARRA_UA_STATUS_BAD_SESSION_NOT_ACTIVATEDActivateSession 失败

例子

DarraUa_Status st = DarraUa_Session_Connect(h);
if (!DARRA_UA_STATUS_IS_GOOD(st)) {
fprintf(stderr, "Connect failed: 0x%08X (%s)\n",
(unsigned)st, DarraUa_StatusName(st));
DarraUa_Session_Close(h);
return -1;
}
printf("Connected, state = %d\n", (int)DarraUa_Session_GetState(h));

DarraUa_Session_Disconnect

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL
DarraUa_Session_Disconnect(DarraUa_SessionHandle h);

主动断开, 句柄保留可重连. 内部:

  1. 停 KeepAlive
  2. 停 AutoPublish (若已启动)
  3. CloseSession + CloseSecureChannel
  4. 触发状态回调 → DARRA_UA_SESSION_DISCONNECTED
/* 重连同一句柄 */
DarraUa_Session_Disconnect(h);
/* ... 等待业务 ... */
DarraUa_Session_Connect(h); /* 同一句柄可重复 Connect */

DarraUa_Session_Close

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL
DarraUa_Session_Close(DarraUa_SessionHandle h);

关闭并释放句柄. 之后 h 不再可用. 若调用时 Session 仍 Connected, 内部先 Disconnect.

DarraUa_Session_Close(h);
h = DARRA_UA_INVALID_SESSION_HANDLE; /* 清零防误用 */

自动重连

cfg.auto_reconnect = 1 时, SDK 检测到底层通讯异常自动:

Connected
↓ (异常)
Reconnecting (状态回调 RECONNECTING)
↓ (重试 reconnect_max_retries 次)
├── 成功 → Connected
└── 失败 → Failed → Disconnected

调整重连参数:

cfg.auto_reconnect        = 1;
cfg.reconnect_max_retries = 5;
cfg.reconnect_delay_ms = 3000;

状态查询

DARRA_OPCUA_API DarraUa_SessionState DARRA_OPCUA_CALL
DarraUa_Session_GetState(DarraUa_SessionHandle h);
DarraUa_SessionState s = DarraUa_Session_GetState(h);
int connected = (s == DARRA_UA_SESSION_CONNECTED);

DarraUa_SessionState 枚举:

含义
DARRA_UA_SESSION_DISCONNECTED (0)未连接 / 已断开
DARRA_UA_SESSION_CONNECTING (1)正在 Connect (Hello / OpenSecureChannel)
DARRA_UA_SESSION_CONNECTED (2)已连接, 可正常 Read / Write / Subscribe
DARRA_UA_SESSION_RECONNECTING (3)检测到断线, 自动重连中
DARRA_UA_SESSION_CLOSING (4)正在 Disconnect / Close
DARRA_UA_SESSION_FAILED (5)重连失败终态, 需要新建实例

详细状态回调 API 见 事件回调.


完整示例

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

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

DarraUa_SessionConfig cfg;
DarraUa_SessionConfig_Init(&cfg);
cfg.endpoint_url = endpoint;
cfg.security_mode = DARRA_UA_MSG_SECURITY_MODE_NONE;
cfg.security_policy_uri = "http://opcfoundation.org/UA/SecurityPolicy#None";
cfg.user_token_type = DARRA_UA_USER_TOKEN_ANONYMOUS;
cfg.auto_reconnect = 1;

DarraUa_SessionHandle h = DARRA_UA_INVALID_SESSION_HANDLE;
DarraUa_Status st = DarraUa_Session_Create(&cfg, &h);
if (!DARRA_UA_STATUS_IS_GOOD(st)) goto cleanup;

st = DarraUa_Session_Connect(h);
if (!DARRA_UA_STATUS_IS_GOOD(st)) {
fprintf(stderr, "Connect failed: 0x%08X (%s)\n",
(unsigned)st, DarraUa_StatusName(st));
goto cleanup;
}
printf("State = %d\n", (int)DarraUa_Session_GetState(h));

/* ... 业务 ... */

DarraUa_Session_Disconnect(h);

cleanup:
if (h) DarraUa_Session_Close(h);
DarraUa_Shutdown();
return 0;
}

下一步