gopcua / opcua

Native Go OPC-UA library
MIT License
871 stars 264 forks source link

Subscription not always resumed after auto reconnect #743

Open Tyslan opened 2 months ago

Tyslan commented 2 months ago

After auto reconnect it seems like subscriptions don't send DataChangeNotification anymore.

I was able to reproduce this issue by changing the subscribe example a little:

  1. I monitor 2 nodeIds (one does exists in the OPC UA server the other one not, which is valid for my use case)
  2. When checking the MonitoredItemsCreateResponse, I just log if there was one result that was not OK instead of panicing.

Initially I receive the DatachangeNotifications of the existing node. If I break the connection between the OPC server and the client, I can see the the reconnection flow is followed. But in the end I see "no subscriptions to resume" in the logs and I receive no longer DatachangeNotifications.

If you do the same with only existing nodes om the servers, you see log messages like "resuming 1 subscriptions" and "resumed 1 subscriptions"

Tyslan commented 2 months ago

For now the following work around seems to work for me:

I'll check if the node I want to subscribe to is a node that has a value attribute. If this check returns an error I do not add it to the MonitoredItemCreateRequest

miRequests := make([]*ua.MonitoredItemCreateRequest, 0, len(nodeIDs))
for i, nodeID := range nodeIDs {
    nid, err := ua.ParseNodeID(nodeID)
    if err != nil {
        slog.Error("Failed to parse nodeID.", "error", err)
        continue
    }
    node := client.Node(nid)
    if _, err := node.Attribute(ctx, ua.AttributeIDValue); err != nil {
        slog.Error("Node is not a value node.", "nodeID", nodeID, "error", err)
    } else {
        miRequests = append(miRequests, valueRequest(nid, uint32(i+1)))
        slog.Info("Node exists.", "nodeID", nodeID)
    }
}

res, err := subscription.Monitor(ctx, ua.TimestampsToReturnBoth, miRequests...)

I'm unsure if this is the proper way of working, but at least it fixes my problem for now.