Client fail to connect to OPC Foundation's Sample Server

Questions regarding the use of the C++ SDK for Server or Client development or integration into customer products ...

Moderator: uasdkcpp

Post Reply
huazhang
Hero Member
Hero Member
Posts: 24
Joined: 09 Sep 2016, 04:39

Client fail to connect to OPC Foundation's Sample Server

Post by huazhang »

Hi support team,

I modified UaSDKCpp client example to connect to OPC Foundation's UA Sample Server which is running on another machine.
Supporse we only know server URL, so we call UaDiscovery's getEndpoint() function to get the server's endpoint descriptions first.
Then we choose a EndpointUrl from one of the endpoint descriptions. In the end, we call UaSession's connect() funtion to connect to server specified by the EndpointUrl.
I failed at connect() funtion, because the EndpointUrl we get from endpoint description is "opc.tcp://localhost:51210/UA/SampleServer".
As the server is running on another machine, we cann't access it through "localhost".
So, what is the correct way to connect to server? Using server URL instead of EndpointUrl?
Here is my code, it's based on UaSDKCpp client example lesson 1: http://documentation.unified-automation ... son01.html

Code: Select all

UaStatus SampleClient::connect()
{
    UaStatus result;

    UaString serverUrl("opc.tcp://vm-27714:51210/UA/SampleServer"); //new code

    // Provide information about the client
    SessionConnectInfo sessionConnectInfo;
    UaString sNodeName("unknown_host");
    char szHostName[256];
    if (0 == UA_GetHostname(szHostName, 256))
    {
        sNodeName = szHostName;
    }
    sessionConnectInfo.sApplicationName = "Unified Automation Getting Started Client";
    // Use the host name to generate a unique application URI
    sessionConnectInfo.sApplicationUri  = UaString("urn:%1:UnifiedAutomation:GettingStartedClient").arg(sNodeName);
    sessionConnectInfo.sProductUri      = "urn:UnifiedAutomation:GettingStartedClient";
    sessionConnectInfo.sSessionName     = sessionConnectInfo.sApplicationUri;

// new code begin
    ServiceSettings serviceSettings;
    ClientSecurityInfo clientSecurityInfo;
    UaEndpointDescriptions endpointDescriptions;
    UaDiscovery discovery;
    result = discovery.getEndpoints(
       serviceSettings,
       serverUrl,
       clientSecurityInfo,
       endpointDescriptions);

    if (result.isNotGood())
    {
       return result;
    }

    OpcUa_UInt32 endpointIndex = 0;
    for (; endpointIndex < endpointDescriptions.length(); ++endpointIndex)
    {
       if (endpointDescriptions[endpointIndex].SecurityMode == OpcUa_MessageSecurityMode_None)
       {
          if (UaString(endpointDescriptions[endpointIndex].SecurityPolicyUri) == OpcUa_SecurityPolicy_None)
          {
             break;
          }
       }
    }

    if (endpointIndex == endpointDescriptions.length())
    {
       return OpcUa_Bad;
    }
//new code end

    // Security settings are not initialized - we connect without security for now
    SessionSecurityInfo sessionSecurityInfo;

    printf("\nConnecting to %s\n", UaString(endpointDescriptions[endpointIndex].EndpointUrl).toUtf8());
    result = m_pSession->connect(
        endpointDescriptions[endpointIndex].EndpointUrl, //new code
        sessionConnectInfo,
        sessionSecurityInfo,
        this);

    if (result.isGood())
    {
        printf("Connect succeeded\n");
    }
    else
    {
        printf("Connect failed with status %s\n", result.toString().toUtf8());
    }

    return result;
}
I download the server application from here: https://opcfoundation.org/developer-too ... plications

Thanks!

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Client fail to connect to OPC Foundation's Sample Server

Post by Support Team »

Hello huazhang,

this is basically an error or configuration error in the OPCF Sample Server. A server should return a hostname or IPAddress where it's reachable. Localhost really is a bad choice.
Calling GetEndpoints and using the EndpointDescrition to get the EndpointUrl is the recommanded way to do it. So your client behaves as expected till here. However a client also should be prepared to handle this issue.

OPC Specification - Part 4 - Chapter 5.5.2.1:
"Clients should be prepared to replace the HostName returned in the EndpointDescription with the
HostName or the IP addresses they used to call GetEndpoints."

You'd run into the same issue if the server returns a correct hostname but hostname resolution doesn't work in the network.
Best regards
Unified Automation Support Team

Post Reply