跳到主要内容

Session 会话 — Session

Session 是 Client 主类, 一个实例对应一个 OPC UA Session. 所有访问 (read / write / browse / subscribe / call / history) 都从这个对象出发.

子页跳转

公共字段 / 属性方法

类别属性类型访问说明
连接endpoint_url()&strR构造时指定的 endpoint URL
handle()u32RC 层句柄 (内部用)
状态state()SessionStateR当前会话状态 (Disconnected / Connecting / Connected / Reconnecting / Closing / Failed)
is_connected()boolR是否已连接 (= state() == Connected)
子对象nodes()NodeCollectionRLazy Load 节点访问器
namespaces()NamespaceCollectionR命名空间 URI ↔ Index 互转
事件eventsArc<Mutex<OpcUaEvents>>RW会话级事件统一通道, 用 .lock() 访问
配置keep_alive_interval_ms()u32RKeepAlive 心跳周期 (默认 10000 ms, 0 = 禁用)
set_keep_alive_interval_ms(ms)()W改心跳周期 (&mut self)
auto_publish()boolR是否启了后台 Publish 线程
set_auto_publish(b)()W启停后台 Publish 线程 (&mut self)

公共方法

构造

连接管理

  • connect(&mut self) — 建立连接 (Hello → SecureChannel → Session → Activate)
  • disconnect(&mut self) — 主动断开, 实例可重连
  • Drop (隐式) — 离开作用域自动 disconnect + close

心跳与发布

  • publish(timeout_ms: u32) -> StatusCode — 手动触发一次 Publish (一般无需调用)

读 / 写

浏览

订阅

方法调用

历史

控制

  • cancel(&self, request_handle: u32) — 取消未完成请求

完整示例

use opcua::{Session, Variant};

fn main() -> Result<(), Box<dyn std::error::Error>> {
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 时自动释放
}

下一步