eclipse / milo

Eclipse Milo™ - an open source implementation of OPC UA (IEC 62541).
http://www.eclipse.org/milo
Eclipse Public License 2.0
1.14k stars 424 forks source link

How to implement Client Redundancy #189

Closed zk230 closed 6 years ago

zk230 commented 6 years ago

I have many client for subscription one opc ua server,but the server is not "milo" server,how to implement Client Redundancy

kevinherron commented 6 years ago

Client Redundancy as described by part 4 of the spec would require that one OpcUaClient instance be able to transfer subscriptions to/from another instance, which isn't currently possible.

The transfer service is callable, but there's no way for the subscription manager in the client taking over the subscriptions to actually take an OpcUaSubscription object and start managing it.

I'll make a ticket to implement this as an enhancement eventually, but the only way I can see it working is if the server also has diagnostics enabled so that the instance taking over subscriptions can learn the details of the subscription (publishing interval, priority, keep-alive count, lifetime count, etc...).

marcus-orchard commented 5 years ago

@kevinherron - would you be ok if I took a stab at implementing this as a PR and associating the commit with this enhancement request?

I agree, the server would need to have diagnostics enabled, otherwise the client should return an error.

Looking at the code, I think this enhancement can be achieved by adding logic to the UaSubscriptionManager/OpcUaSubscriptionManager for transferring a subscription. This could:

  1. Read the value of ServerDiagnostics/EnabledFlag and return an error if false.
  2. Call the transferSubscriptions method in the client
  3. Read the value of relevant SubscriptionDiagnostics for the given subscription ids
  4. Call Server/GetMonitoredItems for each subscription id. This may be possible in parallel to the previous step.
  5. Create an OpcUaSubscription on the client for each subscription using the read diagnostics and add them to the subscriptions Map in the subscription manager.
  6. Using the results of the GetMonitoredItems create the OpcUaMonitoredItem for each subscription locally in the client. I still need to determine how I could provide all the fields for this object's definition, eg ReadValueId. One initial thought would be to set a wasTransferred flag on each monitored item and if true when handling subscription notifications set the missing data from the information returned in the monitored item's notification. Other potential approaches could include ResendData or Republish.
  7. Setting the event/value consumer is a little tricky. I'll not be able to ascertain from the GetMonitoredItems if the monitored item is a value or event. It may be necessary to set both for all transferred items, and then leverage the previously mentioned wasTransferred flag to remove the extraneous consumer at runtime.

Of course I'd be completely open to any suggestions, thoughts, collaborations, or other points of interest you could share.

Is this something you'd be open to?

kevinherron commented 5 years ago

@marcus-orchard I moved this into #523 for discussion.