跳到主要内容

MethodBuilder

概述

OPC UA Call 服务要求把入参打包成 Variant[], 顺序与服务端 InputArguments 对应。MethodBuilder 提供链式 API。

对应规范段: Part 4 §5.11.2 / Part 5 §6.4。

API

方法类别读写说明
new MethodBuilder(ua, objectId, methodId)构造绑定到方法
.loadInputArgs()链式读 InputArguments 描述
.arg(String name, Object value)链式按名设值
.arg(int index, Object value)链式按索引设值
.invoke()终端返回 CallResult { status, outputs }
.getInputArgs()属性LoadInputArgs 后清单

支持 Java 类型: Boolean / Byte / Short / Integer / Long / Float / Double / String / Instant / byte[]

代码示例

import com.darra.opcua.*;

try (DarraOpcUa ua = new DarraOpcUa("opc.tcp://localhost:4840")) {
ua.connect();

// 1) 流式调用 - 按名
CallResult r = new MethodBuilder(ua, "ns=2;s=Robot", "ns=2;s=Robot.MoveTo")
.loadInputArgs()
.arg("x", 100.0)
.arg("y", 200.0)
.arg("speed", 50)
.invoke();

if (r.status != StatusCode.Good)
System.out.println("MoveTo 失败: " + r.status);

// 2) 按索引
CallResult r2 = new MethodBuilder(ua, "ns=2;s=Calc", "ns=2;s=Calc.Add")
.arg(0, 3.14).arg(1, 2.71).invoke();
System.out.println("Add → " + r2.outputs.get(0).asDouble());

// 3) 复用 builder
MethodBuilder b = new MethodBuilder(ua, "ns=2;s=Pump", "ns=2;s=Pump.SetSpeed")
.loadInputArgs();
for (int rpm : new int[]{100, 500, 1000, 1500}) {
CallResult r3 = b.arg("rpm", rpm).invoke();
if (r3.status != StatusCode.Good) break;
Thread.sleep(500);
}
}

与 call 的对比

// 旧写法: 手撸 Variant[]
Variant[] inputs = {
new Variant(100.0), new Variant(200.0), new Variant(50) // 类型?
};
List<Variant> outs = ua.call("ns=2;s=Robot", "ns=2;s=Robot.MoveTo", inputs);

// 新写法
CallResult r = new MethodBuilder(ua, "ns=2;s=Robot", "ns=2;s=Robot.MoveTo")
.loadInputArgs()
.arg("x", 100.0).arg("y", 200.0).arg("speed", 50)
.invoke();

实现限制

  • loadInputArgs 依赖 ExtensionObject 解码, 部分 Server 上 inputArgs 列表可能为空
  • 不支持复杂结构入参
  • invoke 走 call, 失败抛 OpcUaException; 想 Safe 自己包 try/catch

跨语言对照

C#PythonJavaC++RustC
MethodBuilderMethodBuilderMethodBuilderMethodBuilderMethodBuilderDarraUa_MethodBuilder_*

下一步