首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用opcua.Node.Attributes返回EOF错误

调用opcua.Node.Attributes返回EOF错误
EN

Stack Overflow用户
提问于 2022-01-21 13:24:49
回答 1查看 161关注 0票数 1

我正在尝试获取并返回我的OPC模拟服务器的NodeClass Variable的所有节点,从根节点开始,然后遍历所有具有childs的文件夹节点和对象节点。我尝试使用浏览- gopcua repo的例子,但是每当程序第二次到达attrs, err := n.Attributes(...)时,它就会返回一个EOF错误。

我尝试重新创建一个最小的例子:

代码语言:javascript
复制
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/gopcua/opcua"
    "github.com/gopcua/opcua/id"
    "github.com/gopcua/opcua/ua"
)

const (
    endpoint   string = "opc.tcp://<ServerAddress>"
    rootNodeId string = "i=85"
)

func browse(c *opcua.Client, n *opcua.Node) error {
    _, err := n.Attributes(ua.AttributeIDNodeClass, ua.AttributeIDDataType)
    if err != nil {
        return err
    }

    browseChildren := func(refType uint32) error {
        refs, err := n.ReferencedNodes(refType, ua.BrowseDirectionForward, ua.NodeClassAll, true)
        if err != nil {
            return fmt.Errorf("references: %d: %s", refType, err)
        }
        fmt.Printf("found %d child refs\n", len(refs))
        for _, rn := range refs {
            err := browse(c, rn)
            if err != nil {
                return fmt.Errorf("browse children: %s", err)
            }
            fmt.Printf("Found a Node: %s\n", rn.ID.String())
        }
        return nil
    }

    if err := browseChildren(id.HasChild); err != nil {
        return err
    }
    if err := browseChildren(id.Organizes); err != nil {
        return err
    }
    return nil
}

func main() {
    ctx := context.Background()
    c := opcua.NewClient(endpoint)
    if err := c.Connect(ctx); err != nil {
        log.Fatal("Could not connect")
        panic(err)
    }
    defer c.Close()
    id, _ := ua.ParseNodeID(rootNodeId)
    err := browse(c, c.Node(id))
    if err != nil {
        log.Fatal(err)
    }
}

Prosys OPC UA仿真服务器是这样的:

这是我从程序中得到的输出:

代码语言:javascript
复制
found 0 child refs
found 5 child refs
2022/01/21 14:26:06 browse children: EOF
exit status 1
EN

回答 1

Stack Overflow用户

发布于 2022-01-26 09:54:26

tl;dr

代码语言:javascript
复制
browseChildren := func(refType uint32) error {
        refs, err := n.ReferencedNodes(refType, ua.BrowseDirectionForward, ua.NodeClassAll, true)
        if err != nil {
            return fmt.Errorf("references: %d: %s", refType, err)
        }
        fmt.Printf("found %d child refs\n", len(refs))
        for _, rn := range refs {
            refNodeID := ua.MustParseNodeID(rn.ID.String())
            refNode := c.Node(refNodeID) // parse the referenced nodes before usage
            err := browse(c, refNode)
            if err != nil {
                return fmt.Errorf("browse children: %s", err)
            }
            fmt.Printf("Found a Node: %s\n", refNode.ID.String())
        }
        return nil
    }

原因

n.ReferencedNodes返回的引用节点的NodeIDType (64)无效。唯一支持的NodeIDType是0-5。重新解析它们将为它们提供一个合适的NodeIDType。(相关Gitlab问题:https://github.com/gopcua/opcua/issues/550)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70802021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档