连接 / 断开
connect()
pub fn connect(&mut self) -> Result<(), OpcUaError>;
建立到 endpoint 的连接. 内部串行执行:
- Hello — 协商 BufferSize / MaxMessageSize
- OpenSecureChannel — 协商加密通道 (None / Sign / SignAndEncrypt)
- GetEndpoints — 拉取服务端 Endpoint 列表 (用于校验)
- CreateSession — 创建会话, 协商 SessionTimeout
- ActivateSession — 用 UserToken 激活
- 加载 NamespaceArray 到
namespaces() - 自动启
auto_publish = true后台线程 (按auto_publish_on_connect配置) - 自动启 KeepAlive 心跳线程
成功后:
is_connected() == truestate() == SessionState::Connectedevents.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 实例可重连. 内部:
- 停 KeepAlive 线程
- 停 AutoPublish
- 关 native session (CloseSession + CloseSecureChannel)
- 触发
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),
}
}