Professional OPC
Development Tools

logos

How to use UnsubscribeMultipleMonitoredItems in Delphi?

More
11 May 2019 12:31 #7351 by support
I am sorry, I have not formulated it well.
The recommended approach is to unsubscribe from all subscriptions you have made, which can be done using UnsubscribeAllMonitoredItems.
Only by unsubscribing you can assure that the server immediately deletes the subscriptions/session.
If unsubscribing takes time, that is the disadvantage/cost for it.

You can simply terminate the program as well. That is, of course, quicker. Normally that is *not* the recommended approach, because the server is not notified. But, die to various "protective" mechanisms that are built-in to OPC UA, any compliant server will sooner or later detect that the client had "disappeared", and make the cleanup anyway. For some time, however, unnecessary resources remain allocated on the server. If you analyze the situation and come to conclusion that in your particular case, this is OK and makes you app behave better, you can simply "do nothing" at the program termination.

Regards

Please Log in or Create an account to join the conversation.

More
09 May 2019 14:05 #7347 by alr1976
Hi,

so when i close my application i don t need to use
unsubscribe UnsubscribeAllMonitoredItems ?

or i need to use .free?

or nothing?

Thanks Alessandro

Please Log in or Create an account to join the conversation.

More
08 May 2019 09:38 #7345 by support
I am sorry but I cannot give any advice relating to the disconnect method you are calling. It is not a method that we provide. It has to do with OLE infrastructure in Delphi:

- docs.embarcadero.com/products/rad_studio/radstudio2007/RS200...ver_TOleServer_Disconnect.html
- docwiki.embarcadero.com/Libraries/Rio/en/Vcl.OleServer.TOleServer.Disconnect

It is possible that it, in turn, releases the COM object of EasyUAClient, but I am not sure.

Is the Form.Close code for your main form - i.e. does your program terminate when you close that form? If so, you do not have to call anything. What is it that you are trying to achieve, actually?

Regards

Please Log in or Create an account to join the conversation.

More
08 May 2019 08:20 #7344 by alr1976
to close opcuaclient i need to use:
procedure FormClose(Sender: TObject; var Action: TCloseAction);
begin

Client.disconnect;

or
Client. UnsubscribeAllMonitoredItems;
Client.disconnect;

end;

Please Log in or Create an account to join the conversation.

More
03 May 2019 08:00 - 03 May 2019 08:00 #7341 by support
And, before you get a chance to answer, here is some information to how it works:

When you unsubscribe just some of the monitored items in a UA subscription, QuickOPC will call the OPC UA DeleteMonitoredItems service, with only those that are being unsubscribed.

QuickOPC, however, contains an optimization: If you unsubscribe *all* remaining items in a subscription (either by specifying them explicitly, or with the UnsubscribeAllMonitoredItems call), it will *not* call the DeleteMonitoredItems service. Instead, it will directly call the OPC UA DeleteSubscription service, which does not require the items be listed one by one, and is thus shorter to communicate and should be faster on the server to process. So, you should be all good in this respect.

Even after you unsubscribe from everything, QuickOPC holds the connection open for some time; it will come to something between 5-15 seconds I believe. If this is what bothers you, it can be configured directly.

Also, please elaborate on what you mean by ".... It take much time of opcua server Is far.". *What* is it that takes long? Is the execution waiting in some of the QuickOPC call, or where (which point in you program)?

Regards
Last edit: 03 May 2019 08:00 by support.

Please Log in or Create an account to join the conversation.

More
03 May 2019 04:14 #7339 by support
Hello.

what do you mean by "I use only disconnect"? Does it mean
- exiting the program normally but without calling UnsubscribeAllMonitoredItems,
- somehow abruptly terminating the program,
- somehow physically disrupting the network communication (unplugging the cable),
- or something different (what)?

Thank you

Please Log in or Create an account to join the conversation.

More
02 May 2019 05:38 #7337 by alr1976
Hi!
When i close opcuaclient i must always use
Client.UnsubscribeAllMonitoredItems or can i use only disconnect?
If i use Client.UnsubscribeAllMonitoredItems before disconnect It take much time of opcua server Is far.

BR Alessandro

Please Log in or Create an account to join the conversation.

More
08 Feb 2019 08:38 #7072 by support
Hello.

I have created an example which shows how to pick just *some* items you have previously subscribed to, and unsubscribe just from them. By doing so, the example also shows the way how you can construct the handle array that is the input to the UnsubscribeMultipleMonitoredItems. With that knowledge, you should be able to create the array based on the size of your string list, and then fill in the elements of the array with the elements from string list, converted to integers. The conversion part is a general programming question and does not belong to this forum. Many years ago I have worked with Pascal, so if I remember well there is Val function for that.

// This example shows how to unsubscribe from changes of just some monitored
// items.
 
{
type
  TClientEventHandlers = class
    procedure OnDataChangeNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUADataChangeNotificationEventArgs);
  end;
 
procedure TClientEventHandlers.OnDataChangeNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUADataChangeNotificationEventArgs);
begin
  // Display the data
  // Remark: Production code would check eventArgs.Exception before accessing
  // eventArgs.AttributeData.
	WriteLn(eventArgs.Arguments.NodeDescriptor.ToString, ': ',
    eventArgs.AttributeData.ToString);
end;
}
 
class procedure UnsubscribeMultipleMonitoredItems.Some;
var
  Arguments: OleVariant;
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers;
  Handle: Cardinal;
  HandleArray: OleVariant;
  HandleSafeArray: PSafeArray;
  I: Cardinal;
  MonitoredItemArguments1, MonitoredItemArguments2, MonitoredItemArguments3:
    _EasyUAMonitoredItemArguments;
  MonitoringParameters: _UAMonitoringParameters;
  SelectedHandles: OleVariant;
begin
  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers.Create;
  Client.OnDataChangeNotification := ClientEventHandlers.OnDataChangeNotification;
 
  WriteLn;
  WriteLn('Subscribing...');
  MonitoringParameters := CoUAMonitoringParameters.Create;
  MonitoringParameters.SamplingInterval := 1000;
  MonitoredItemArguments1 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments1.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  MonitoredItemArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10845';
  MonitoredItemArguments1.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments2 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments2.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  MonitoredItemArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10853';
  MonitoredItemArguments2.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments3 := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments3.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  MonitoredItemArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10855';
  MonitoredItemArguments3.MonitoringParameters := MonitoringParameters;
  Arguments := VarArrayCreate([0, 2], varVariant);
  Arguments[0] := MonitoredItemArguments1;
  Arguments[1] := MonitoredItemArguments2;
  Arguments[2] := MonitoredItemArguments3;
 
  HandleSafeArray := Client.SubscribeMultipleMonitoredItems(PSafeArray(TVarData(Arguments).VArray));
  TVarData(HandleArray).VType := varArray or varVariant;
  TVarData(HandleArray).VArray := PVarArray(HandleSafeArray);
 
  for I := VarArrayLowBound(HandleArray, 1) to VarArrayHighBound(HandleArray, 1) do
  begin
      Handle := Cardinal(HandleArray[I]);
      WriteLn('HandleArray[', I, ']: ', Handle);
  end;
 
  WriteLn;
  WriteLn('Processing monitored item changed events for 10 seconds...');
  PumpSleep(10*1000);
 
  WriteLn;
  WriteLn('Unsubscribing from 2 monitored items...');
  SelectedHandles := VarArrayCreate([0, 1], varVariant);
  // We will unsubscribe from the first and third monitored item we have
  // previously subscribed to.
  SelectedHandles[0] := HandleArray[0];
  SelectedHandles[1] := HandleArray[2];
  Client.UnsubscribeMultipleMonitoredItems(PSafeArray(TVarData(SelectedHandles).VArray));
 
  WriteLn;
  WriteLn('Processing monitored item changed events for 10 seconds...');
  PumpSleep(10*1000);
 
  WriteLn;
  WriteLn('Unsubscribing from all remaining monitored items...');
  Client.UnsubscribeAllMonitoredItems;
 
  WriteLn;
  WriteLn('Waiting for 5 seconds...');
  Sleep(5*1000);
 
  WriteLn;
  WriteLn('Finished.');
  FreeAndNil(Client);
  FreeAndNil(ClientEventHandlers);
end;

I hope this helps
Best regards

Please Log in or Create an account to join the conversation.

More
07 Feb 2019 07:50 #7070 by alr1976
Hi!

I know but my app subscribe tags when i Need so i store It in tstringlist. I Need to unsubscribe It when i don t Need anymore. So i have subscribeid list in a tstringlist.

So how convert subscribeid in a tstringlist to handlearray Array?

Please Log in or Create an account to join the conversation.

More
07 Feb 2019 06:41 #7069 by support
The handles returned from SubscribeXXXX methods *are* integers. No conversions should be needed.

If this is still not clear or does not work, let me know and I will prepare some example directly in Delphi.

Best regards

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.210 seconds

      

 Recommend this on Google