基于opcua-asyncio实现GDS的CreateSigningRequest方法遇阻求助
解决opcua-asyncio调用GDS CreateSigningRequest方法的BadMethodInvalid错误
错误原因
你使用的ObjectIds.CreateSigningRequestMethodType是方法的类型定义节点,而非挂载在ServerConfiguration对象上的实际方法实例节点。OPC UA规范要求调用方法时,必须使用绑定到目标对象的实例节点,不能直接用类型ID调用。
解决步骤
1. 定位实际的方法实例节点
首先需要找到ServerConfiguration对象下的CreateSigningRequest方法实例。可以通过浏览子节点的方式确认:
async with client: server_config = client.get_node(ObjectIds.ServerConfiguration) # 遍历ServerConfiguration的子节点,筛选方法类型节点 children = await server_config.get_children() for child in children: node_class = await child.get_node_class() if node_class == ua.NodeClass.Method: browse_name = await child.get_browse_name() print(f"方法名称: {browse_name.Name}, NodeId: {child.nodeid}")
运行这段代码后,控制台会输出ServerConfiguration下所有方法的信息,找到CreateSigningRequest对应的NodeId。
2. 修正代码调用方法
用找到的实际方法实例节点替换原代码中的类型节点,或者直接通过BrowseName获取(标准GDS服务器中该方法的BrowseName为CreateSigningRequest,命名空间索引为0):
client = Client(url=url) await client.set_security( SecurityPolicyBasic256Sha256, certificate=r"C:\other\my_cert.der", private_key=r"C:\other\my_private_key.pem", ) async with client: server_config = client.get_node(ObjectIds.ServerConfiguration) # 通过BrowseName获取实际方法节点(推荐,无需手动复制NodeId) csr_method = server_config.get_child(["0:CreateSigningRequest"]) # 构造符合GDS规范的参数 args = ( ua.Variant( ua.NodeId(ObjectIds.ServerConfigurationType_CertificateGroups_DefaultApplicationGroup), ua.VariantType.NodeId), ua.Variant( ua.NodeId(ObjectIds.RsaSha256ApplicationCertificateType), ua.VariantType.NodeId), ua.Variant("", ua.VariantType.String), ua.Variant(False, ua.VariantType.Boolean), ua.Variant(b"", ua.VariantType.ByteString) ) # 调用方法 cert = await server_config.call_method(csr_method, *args)
额外注意事项
- 如果
get_child方式获取失败,直接使用第一步浏览到的具体NodeId替换csr_method的值即可。 - 核对参数是否完全符合GDS规范:参数依次为
CertificateGroupId、CertificateTypeId、SubjectName、RegeneratePrivateKey、Nonce,你的参数结构是正确的,若调用后仍有错误可检查参数的具体值是否匹配GDS服务器要求。
内容的提问来源于stack exchange,提问作者piotrek204
相关产品推荐
相关产品推荐

