QuickOPC User's Guide and Reference
OPC UA Local Discovery
View with Navigation Tools
Development Models > Imperative Programming Model > Imperative Programming Model for OPC Data (Classic and UA) > Browsing for Information (OPC Data) > Discovering OPC UA Servers > OPC UA Local Discovery
In This Topic

QuickOPC-UA allows you to work with so called OPC-UA Local Discovery Server(s). OPC-UA Local Discovery Server is a special OPC-UA service that provides information about other OPC-UA servers available.

The term "local discovery" might be misleading sometimes. OPC UA Local Discovery is not just for discovering OPC UA servers that reside on the same computer as where your OPC UA client is. OPC UA Local Discover allows you to discover servers on a remote computer as well, provided that you know the host name of the computer, and the OPC UA Local Discovery Server is running on that remote computer.

If you want to retrieve a list of OPC Unified Architecture servers registered on a local or remote computer, call the DiscoverLocalServers method, passing it the name or address of the remote machine.

You will receive back a UADiscoveryElementCollection object, which is collection of UADiscoveryElement-s. Each element contains a server's discovery URL. The discovery URL is the main piece of information that you can further use if you want to connect to that OPC-UA server. Each UADiscoveryElement contains information gathered about one OPC server found by the discovery process, including things like the application name, application type, its Product URI etc.

.NET

// This example shows how to obtain application URLs of all OPC Unified Architecture servers on a given machine.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Discovery;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    class DiscoverLocalServers
    {
        public static void Overload1()
        {
            // Instantiate the client object.
            var client = new EasyUAClient();

            // Obtain collection of server elements.
            UADiscoveryElementCollection discoveryElementCollection;
            try
            {
                discoveryElementCollection = client.DiscoverLocalServers("opcua.demo-this.com");
            }
            catch (UAException uaException)
            {
                Console.WriteLine($"*** Failure: {uaException.GetBaseException().Message}");
                return;
            }

            // Display results.
            foreach (UADiscoveryElement discoveryElement in discoveryElementCollection)
                Console.WriteLine($"discoveryElementCollection[\"{discoveryElement.DiscoveryUriString}\"].ApplicationUriString: {discoveryElement.ApplicationUriString}");

            
            // Example output:
            //
            //discoveryElementCollection["opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"].ApplicationUriString: urn: DEMO - 5:UA Sample Server
            //discoveryElementCollection["http://opcua.demo-this.com:51211/UA/SampleServer"].ApplicationUriString: urn: DEMO - 5:UA Sample Server
            //discoveryElementCollection["https://opcua.demo-this.com:51212/UA/SampleServer/"].ApplicationUriString: urn: DEMO - 5:UA Sample Server
            //discoveryElementCollection["http://opcua.demo-this.com:62543/Quickstarts/AlarmConditionServer"].ApplicationUriString: urn: opcua.demo - this.com:Quickstart Alarm Condition Server
            //discoveryElementCollection["opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"].ApplicationUriString: urn: opcua.demo - this.com:Quickstart Alarm Condition Server
        }
    }
}

COM

// This example shows how to obtain application URLs of all OPC Unified Architecture servers on the specified host.

#include "stdafx.h"    // Includes "QuickOpc.h", and other commonly used files
#include "DiscoverLocalServers.h"

namespace _EasyUAClient
{
    void DiscoverLocalServers::Main()
    {
        // Initialize the COM library
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
        {
            // Instantiate the client object
            _EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));

            // Obtain collection of server elements
            _UADiscoveryElementCollectionPtr DiscoveryElementsPtr = ClientPtr->DiscoverLocalServers(L"opcua.demo-this.com");
    
            // Display results
            IEnumVARIANTPtr EnumDiscoveryElementPtr = DiscoveryElementsPtr->GetEnumerator();
            _variant_t vDiscoveryElement;
            while (EnumDiscoveryElementPtr->Next(1, &vDiscoveryElement, NULL) == S_OK)
            {
                _UADiscoveryElementPtr DiscoveryElementPtr(vDiscoveryElement);
                _tprintf(_T("DiscoveryElementCollection[\"%s\"]: "), (LPCTSTR)CW2CT(DiscoveryElementPtr->DiscoveryUriString));
                _tprintf(_T("%s\n"), (LPCTSTR)CW2CT(DiscoveryElementPtr->ApplicationUriString));
                vDiscoveryElement.Clear();
            }
        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}

 

In .NET, if you want to connect to the discovered OPC server later in your code by calling other methods, use the built-in conversion of UADiscoveryElement to UAEndpointDescriptor, and pass the resulting object as an endpointDescriptor argument either directly to some other method call.

When performing a local discovery of OPC-UA servers, the component attempts to connect to multiple possible discovery endpoints in parallel, speeding up the discovery. This behavior is controlled by the ParallelDiscovery property in the UADiscoveryParameters object. The endpoints that the components attempts to use for discovery on a given host (either sequentially, or in parallel), are given by the DiscoveryUriTemplateStrings property of the UAHostParameters.

You can also bypass the use of UAHostParameters, and call the DiscoverLocalServers overload that takes an input array or URL strings to attempt discovery on.

There are also DiscoverLocalApplications methods, which allow you to specify the application types you are interested in, using the combination of flags from the UAApplicationTypes enumeration. This can be useful e.g. if you want to do hierarchical discovery and return also the discovery servers (which are not returned by default).

The FindLocalApplications method can be used, if you want to interrogate specific discovery endpoints.

.NET

// This example shows how to obtain application URLs of all OPC Unified Architecture servers, using specified discovery URI
// strings.

using System;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Discovery;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    class FindLocalApplications
    {
        public static void Main1()
        {

            string[] discoveryUriStrings =
            {
                "opc.tcp://opcua.demo-this.com:4840/UADiscovery",
                "http://opcua.demo-this.com/UADiscovery/Default.svc",
                "http://opcua.demo-this.com:52601/UADiscovery"
            };

            // Instantiate the client object.
            var client = new EasyUAClient();

            // Obtain collection of application elements.
            UADiscoveryElementCollection discoveryElementCollection;
            try
            {
                discoveryElementCollection = client.FindLocalApplications(discoveryUriStrings, UAApplicationTypes.Server);
            }
            catch (UAException uaException)
            {
                Console.WriteLine($"*** Failure: {uaException.GetBaseException().Message}");
                return;
            }

            // Display results.
            foreach (UADiscoveryElement discoveryElement in discoveryElementCollection)
                Console.WriteLine($"discoveryElementCollection[\"{discoveryElement.DiscoveryUriString}\"].ApplicationUriString: {discoveryElement.ApplicationUriString}");


            // Example output:
            //discoveryElementCollection["http://opcua.demo-this.com:62543/Quickstarts/AlarmConditionServer"].ApplicationUriString: urn:opcua.demo-this.com:Quickstart Alarm Condition Server
            //discoveryElementCollection["opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"].ApplicationUriString: urn:opcua.demo-this.com:Quickstart Alarm Condition Server
            //discoveryElementCollection["opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"].ApplicationUriString: urn:opcua.demo-this.com:UA Sample Server
            //discoveryElementCollection["http://opcua.demo-this.com:51211/UA/SampleServer"].ApplicationUriString: urn:opcua.demo-this.com:UA Sample Server
            //discoveryElementCollection["https://opcua.demo-this.com:51212/UA/SampleServer/"].ApplicationUriString: urn:opcua.demo-this.com:UA Sample Server
            //discoveryElementCollection["opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"].ApplicationUriString: urn:Test-PC:UA Sample Server
        }
    }
}

COM

// This example shows how to obtain application URLs of all OPC Unified Architecture servers, using specified discovery URI strings.

class procedure FindLocalApplications.Main;
const
  UAApplicationTypes_Server = 1;
var
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  Count: Cardinal;
  Element: OleVariant;
  DiscoveryElement: _UADiscoveryElement;
  DiscoveryElementEnumerator: IEnumVariant;
  DiscoveryElements: _UADiscoveryElementCollection;
  DiscoveryUriStrings: OleVariant;
begin
  DiscoveryUriStrings := VarArrayCreate([0, 2], varVariant);
  DiscoveryUriStrings[0] := 'opc.tcp://opcua.demo-this.com:4840/UADiscovery';
  DiscoveryUriStrings[1] := 'http://opcua.demo-this.com/UADiscovery/Default.svc';
  DiscoveryUriStrings[2] := 'http://opcua.demo-this.com:52601/UADiscovery';

  // Instantiate the client object
  Client := CoEasyUAClient.Create;

  // Obtain collection of application elements
  try
    DiscoveryElements := Client.FindLocalApplications(DiscoveryUriStrings, UAApplicationTypes_Server);
  except
    on E: EOleException do
    begin
      WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
      Exit;
    end;
  end;

  // Display results
  DiscoveryElementEnumerator := DiscoveryElements.GetEnumerator;
  while (DiscoveryElementEnumerator.Next(1, Element, Count) = S_OK) do
  begin
    DiscoveryElement := IUnknown(Element) as _UADiscoveryElement;
    WriteLn(
      'DiscoveryElements["',
      DiscoveryElement.DiscoveryUriString,
      '".ApplicationUriString: ',
      DiscoveryElement.ApplicationUriString);
  end;

  VarClear(DiscoveryUriStrings);
end;

 

Note that QuickOPC returns UADiscoveryElementCollection from all OPC UA discovery methods, but the amount of information contained in each returned UADiscoveryElement depends on the discovery approach used. For OPC UA Local Discovery, following primary properties of each UADiscoveryElement are filled in:

OPC UA Local Discovery Server (LDS) is not part of QuickOPC installation.
See Also

Installed Examples - Web