Session 会话 — Session
Session 是 Client 主类, 一个实例对应一个 OPC UA Session. 所有访问 (read / write / browse / subscribe / call / history) 都从这个对象出发.
子页跳转
- 构造与连接参数请参考 构造函数.
- 连接 / 断开请参考 连接管理.
- 单点 / 批量读写请参考 Read / Write.
- 内部事件统一通道请参考 Events.
- 命名空间反查请参考 Namespaces.
- 心跳与会话保活请参考 KeepAlive.
公共字段 / 属性方法
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 连接 | endpoint_url() | &str | R | 构造时指定的 endpoint URL |
handle() | u32 | R | C 层句柄 (内部用) | |
| 状态 | state() | SessionState | R | 当前会话状态 (Disconnected / Connecting / Connected / Reconnecting / Closing / Failed) |
is_connected() | bool | R | 是否已连接 (= state() == Connected) | |
| 子对象 | nodes() | NodeCollection | R | Lazy Load 节点访问器 |
namespaces() | NamespaceCollection | R | 命名空间 URI ↔ Index 互转 | |
| 事件 | events | Arc<Mutex<OpcUaEvents>> | RW | 会话级事件统一通道, 用 .lock() 访问 |
| 配置 | keep_alive_interval_ms() | u32 | R | KeepAlive 心跳周期 (默认 10000 ms, 0 = 禁用) |
set_keep_alive_interval_ms(ms) | () | W | 改心跳周期 (&mut self) | |
auto_publish() | bool | R | 是否启了后台 Publish 线程 | |
set_auto_publish(b) | () | W | 启停后台 Publish 线程 (&mut self) |
公共方法
构造
| 方法 | 说明 |
|---|---|
Session::new(url: &str) | 简化构造 (None 安全, 匿名) |
Session::with_config(cfg: ConnectionConfig) | 全配置构造 (加密 / Username / 超时全部) |
连接管理
| 方法 | 说明 |
|---|---|
connect(&mut self) | 建立连接 (Hello → SecureChannel → Session → Activate) |
disconnect(&mut self) | 主动断开, 实例可重连 |
Drop (隐式) | 离开作用域自动 disconnect + close |
心跳与发布
| 方法 | 说明 |
|---|---|
publish(timeout_ms: u32) -> StatusCode | 手动触发一次 Publish (一般无需调用) |
读 / 写
浏览
| 方法 | 说明 |
|---|---|
browse(&self, node_id, filter) | 单层浏览 |
browse_many(&self, node_ids, filter) | 批量浏览 |
browse_with_paging(&self, node_id, filter) | 含 ContinuationPoint 翻页支持 |
browse_next(&self, cp, release) | 续翻分页 |
browse_all(&self, node_id, filter, max_pages) | 自动循环 BrowseNext |
translate_browse_paths(&self, paths) | 路径批量解析为 NodeId |
resolve(&self, path) | 单条绝对路径解析 |
resolve_from(&self, start_node_id, path) | 单条相对路径解析 |
register_nodes(&self, node_ids) | 注册临时高效 NodeId |
unregister_nodes(&self, registered_ids) | 注销临时 NodeId |
订阅
| 方法 | 说明 |
|---|---|
create_subscription(&self, interval_ms: f64) | 创建数据订阅 |
subscribe_events(&self, node_id, existing, callback) | 订阅事件 (报警 / 条件) |
transfer_subscriptions(&self, sub_ids, send_initial_values) | 跨 Session 迁移订阅 |
方法调用
| 方法 | 说明 |
|---|---|
call(&self, object_id, method_id, &[Variant]) | 调用 OPC UA Method 节点 |
历史
| 方法 | 说明 |
|---|---|
read_history(&self, node_id, start, end, max_values) | 读原始历史 |
read_history_modified(...) | 读含修改记录的历史 |
read_history_at_time(...) | 读指定时间点的内插值 |
read_history_processed(...) | 聚合 (Average / Min / Max / TimeAverage / ...) |
read_history_events(...) | 读历史事件 |
update_history(...) | Insert / Replace / Update / Remove 历史 |
delete_history_range(...) | 按区间删除历史 |
控制
| 方法 | 说明 |
|---|---|
cancel(&self, request_handle: u32) | 取消未完成请求 |
完整示例
use darra_opcua::{Session, Variant};
fn main() -> Result<(), Box<dyn std::error::Error>> {
darra_opcua::initialize()?;
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_disconnected.push(Box::new(|e| {
println!("Disconnected: {}", e.status_code);
}));
s.connect()?;
// 读
let dv = s.read("ns=2;s=Temperature")?;
println!("T = {} °C", dv.variant().try_get_f64().unwrap_or(0.0));
// 写
let mut v = Variant::new();
v.set_f64(42.0);
let st = s.write("ns=2;s=Setpoint", &v)?;
println!("Write status = {}", st);
// 订阅
let sub = s.create_subscription(500.0)?;
sub.add_node("ns=2;s=Counter", |args| {
println!("{:?} = {:?} ({})",
args.node_id, args.value_string, args.status);
})?;
// 方法
let mut a = Variant::new(); a.set_i32(3);
let mut b = Variant::new(); b.set_i32(4);
let outputs = s.call("ns=2;s=Calc", "ns=2;s=Calc.Add", &[a, b])?;
for v in &outputs {
println!("sum = {}", v.try_get_i32().unwrap_or(0));
}
std::thread::sleep(std::time::Duration::from_secs(60));
Ok(()) // s / sub Drop 时自动释放
}