跳到主要内容

连接 / 断开

前置阅读

connect()

pub fn connect(&mut self) -> Result<(), OpcUaError>;

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

  1. Hello — 协商 BufferSize / MaxMessageSize
  2. OpenSecureChannel — 协商加密通道 (None / Sign / SignAndEncrypt)
  3. GetEndpoints — 拉取服务端 Endpoint 列表 (用于校验)
  4. CreateSession — 创建会话, 协商 SessionTimeout
  5. ActivateSession — 用 UserToken 激活
  6. 加载 NamespaceArray 到 namespaces()
  7. 自动启 auto_publish = true 后台线程 (按 auto_publish_on_connect 配置)
  8. 自动启 KeepAlive 心跳线程

成功后:

  • is_connected() == true
  • state() == SessionState::Connected
  • events.lock().unwrap().on_connected 列表里的回调被触发

失败返回 Err(OpcUaError), 字段 status 携带具体 StatusCode (BAD_CERTIFICATE_INVALID / BAD_IDENTITY_TOKEN_REJECTED / BAD_COMMUNICATION_ERROR / ...).

例子

use darra_opcua::Session;

let mut s = Session::new("opc.tcp://localhost:4840")?;

s.events.lock().unwrap().on_connected.push(Box::new(|e| {
println!("Connected to {}", e.endpoint_url);
}));
s.events.lock().unwrap().on_state_changed.push(Box::new(|e| {
println!("{:?} -> {:?} (reason={})", e.old_state, e.new_state, e.reason);
}));

match s.connect() {
Ok(()) => println!("connected"),
Err(e) => eprintln!("Connect failed: {} (status={})", e.message, e.status),
}

disconnect()

pub fn disconnect(&mut self) -> Result<(), OpcUaError>;

主动断开连接, 但保留 Session 实例可重连. 内部:

  1. 停 KeepAlive 线程
  2. 停 AutoPublish
  3. 关 native session (CloseSession + CloseSecureChannel)
  4. 触发 events.on_disconnected("主动断开")

Drop 自动 Disconnect + Close, 一般依赖作用域即可, 不需要显式 disconnect().

重连同一实例

s.disconnect()?;
// ... 等待 / 业务处理 ...
s.connect()?; // 同一实例可以多次 Connect

自动重连 (内置)

SDK 检测到底层通讯异常时自动:

Connected
↓ (异常)
Reconnecting (on_reconnecting 触发)
↓ (重试 reconnect_max_retries 次, 默认 3)
├── 成功 → Reconnected (on_reconnected 触发) → 自动 Republish 订阅
└── 失败 → Disconnected (on_disconnected 触发)

重连参数通过 ConnectionConfig 设置:

use darra_opcua::{Session, ConnectionConfig};

let mut cfg = ConnectionConfig::new("opc.tcp://server:4840");
cfg.auto_reconnect = true;
cfg.reconnect_max_retries = 5;
cfg.reconnect_delay_ms = 3000;
let mut s = Session::with_config(cfg)?;

状态查询

use darra_opcua::SessionState;

let st: SessionState = s.state();
// Disconnected / Connecting / Connected / Reconnecting / Closing / Failed

let ok: bool = s.is_connected(); // == (state() == Connected)

SessionState 枚举:

含义
Disconnected未连接 / 已断开
Connecting正在 connect (Hello / OpenSecureChannel)
Connected已连接, 可正常 read / write / subscribe
Reconnecting检测到断线, 自动重连中
Closing正在 disconnect / Drop
Failed重连失败终态, 需要新建实例

借用模式说明

方法借用原因
connect&mut self启 KeepAlive 线程, 改 keep_alive_thread 字段
disconnect&mut self停线程, 改 keep_alive_thread 字段
state / is_connected&self只读原子量
read / write / browse&self走 RPC, 不改本地配置

异常路径示例

match s.connect() {
Ok(()) => println!("connected"),
Err(e) => match e.status {
darra_opcua::StatusCode::BAD_CERTIFICATE_INVALID
=> eprintln!("证书校验失败"),
darra_opcua::StatusCode::BAD_IDENTITY_TOKEN_REJECTED
=> eprintln!("用户名/密码错误"),
darra_opcua::StatusCode::BAD_COMMUNICATION_ERROR
=> eprintln!("网络不通"),
_ => eprintln!("其他错误: {}", e),
}
}

下一步