跳到主要内容

Session 会话 (C)

C SDK 的 Session 不是对象, 而是 DarraUa_SessionHandle (uint32_t) 标识的内部上下文. 所有 DarraUa_Session_* 函数第一个参数都是这个 handle.

声明位于 <darra_opcua/darra_opcua_session.h>, 已被主头 darra_opcua.h 包含.

子页跳转

句柄类型

typedef uint32_t DarraUa_SessionHandle;
#define DARRA_UA_INVALID_SESSION_HANDLE 0u

0 是非法值, 所有 _Create 类函数失败时把出参置零, 上层用比较法判失败.

公共配置字段 (DarraUa_SessionConfig)

类别属性类型访问说明
连接endpoint_urlconst char*inOPC UA endpoint, 如 opc.tcp://host:4840
security_modeDarraUa_MessageSecurityModeinNone / Sign / SignAndEncrypt
security_policy_uriconst char*inSecurityPolicy URI (#None / #Basic256Sha256)
登录user_token_typeDarraUa_UserTokenTypeinAnonymous / Username / Certificate / Issued
usernameconst char*inuser_token_type=USERNAME 时使用
passwordconst char*in配 username 用
证书client_cert_pathconst char*in客户端 PFX 路径 (Sign 必填)
client_key_pathconst char*inPFX 密码 (字段复用)
server_cert_pathconst char*in服务端 DER, NULL = TOFU
超时session_timeout_msuint32_tin服务端 Session 超时, 默认 600000 (10 分钟)
connect_timeout_msuint32_tin建链超时, 默认 10000 (10 秒)
request_timeout_msuint32_tin单 RPC 超时, 默认 10000 (10 秒)
keepalive_interval_msuint32_tin心跳周期, 默认 10000, 0 = 禁用
重连auto_reconnectuint32_tin1 = 启用, 0 = 不重连
reconnect_max_retriesuint32_tin默认 3
reconnect_delay_msuint32_tin默认 2000

务必先调 DarraUa_SessionConfig_Init(&cfg) 把所有字段填默认值, 再覆写需要的字段.


完整 API 速查

生命周期

函数说明
DarraUa_SessionConfig_Init(&cfg)填默认值
DarraUa_Session_Create(&cfg, &h)创建句柄 (尚未连接)
DarraUa_Session_Connect(h)Hello → SecureChannel → Session → Activate
DarraUa_Session_Disconnect(h)主动断开, 句柄保留可重连
DarraUa_Session_Close(h)关闭并释放句柄

状态

函数说明
DarraUa_Session_GetState(h)返回 DarraUa_SessionState 枚举
DarraUa_Session_SetStateCallback(h, cb, ctx)注册状态变更回调

读 / 写

函数说明
DarraUa_Session_ReadNode(h, "i=2258", attr, &st)字符串 NodeId 单节点读
DarraUa_Session_Read(h, items, n, out_dvs)批量读 (结构体数组)
DarraUa_Session_ReadNodes(h, ids, attrs, n, out_dvs)批量读 (字符串数组)
DarraUa_Session_WriteNode(h, "ns=2;s=X", attr, v)字符串 NodeId 单节点写
DarraUa_Session_Write(h, items, n, out_results)批量写

浏览 / 路径解析

函数说明
DarraUa_Session_BrowseNode(h, "i=84", filter, &res)单节点 (字符串)
DarraUa_Session_Browse(h, &node_id, filter, &res)单节点 (结构体)
DarraUa_Session_BrowseNodes(h, ids, n, filter, results)批量浏览
DarraUa_Session_BrowseNext(h, release, cp, cp_len, &res)续翻分页
DarraUa_Session_TranslateBrowsePaths(h, ...)路径批量解析
DarraUa_Session_ResolveBrowsePath(h, start, path, buf, bufSz)单条相对路径解析
DarraUa_Session_RegisterNodes(h, ids, n, &out)注册临时高效 NodeId
DarraUa_Session_UnregisterNodes(h, ids, n)注销

命名空间

函数说明
DarraUa_Session_LoadNamespaceArray(h)强制重读 i=2255
DarraUa_Session_GetNamespaceCount(h)命名空间数
DarraUa_Session_GetNamespaceUri(h, idx)URI 查询
DarraUa_Session_FindNamespaceIndex(h, uri)反查 URI → Index

订阅

函数说明
DarraUa_Subscription_Create(h, &cfg, &sub)创建数据订阅
DarraUa_Session_Publish(h, timeout_ms)手动 Pump
DarraUa_Session_StartAutoPublish(h) / _Stop后台 Publish 线程
DarraUa_Session_TransferSubscriptions(...)跨 Session 迁移订阅

方法 / 历史

函数说明
DarraUa_Session_Call(h, &obj, &method, args, n, &out, &nout, &st)Call OPC UA Method
DarraUa_Session_HistoryRead*(...)5 模式 HistoryRead
DarraUa_Session_HistoryUpdateData / HistoryDeleteRange写 / 删历史

控制

函数说明
DarraUa_Session_Cancel(h, request_handle, &cancelled_count)取消未完成请求

状态机

typedef enum {
DARRA_UA_SESSION_DISCONNECTED = 0,
DARRA_UA_SESSION_CONNECTING = 1,
DARRA_UA_SESSION_CONNECTED = 2,
DARRA_UA_SESSION_RECONNECTING = 3,
DARRA_UA_SESSION_CLOSING = 4,
DARRA_UA_SESSION_FAILED = 5
} DarraUa_SessionState;

调用流向:

Disconnected
↓ Session_Connect
Connecting

Connected
↓ (网络异常 + auto_reconnect=1)
Reconnecting
├── 成功 → Connected
└── 失败 → Failed → Closing → Disconnected

完整示例

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

#if defined(_WIN32)
# include <windows.h>
# define OPCUA_SLEEP_SEC(s) Sleep((s) * 1000)
#else
# include <unistd.h>
# define OPCUA_SLEEP_SEC(s) sleep(s)
#endif

static void on_state(DarraUa_SessionHandle h, DarraUa_SessionState st,
DarraUa_Status code, void* ctx)
{
(void)h; (void)ctx;
printf("Session state -> %d (status 0x%08X)\n", (int)st, (unsigned)code);
}

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;

DarraUa_SessionHandle h = DARRA_UA_INVALID_SESSION_HANDLE;
if (!DARRA_UA_STATUS_IS_GOOD(DarraUa_Session_Create(&cfg, &h))) goto cleanup;
DarraUa_Session_SetStateCallback(h, on_state, NULL);
if (!DARRA_UA_STATUS_IS_GOOD(DarraUa_Session_Connect(h))) goto cleanup;

/* Read */
DarraUa_Status st = 0;
DarraUa_DataValue* dv = DarraUa_Session_ReadNode(
h, "i=2258", DARRA_UA_ATTR_VALUE, &st);
if (dv) {
DarraUa_DateTime ft = DarraUa_Variant_GetDateTime(
DarraUa_DataValue_GetValue(dv));
printf("CurrentTime ft=%lld\n", (long long)ft);
DarraUa_DataValue_Delete(dv);
}

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

下一步