Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

EasyUAClient - browsing, user authentication with a certificate, etc.

More
15 Oct 2014 13:37 - 15 Oct 2014 13:38 #2436 by support
Can you please answer:
  1. Please confirm that you get the timeout *always* (no operation succeeds)
  2. Do you get truly get the timeout after 60 seconds of waiting, or in substantially shorter or longer time?
  3. Please confirm that there are no additional pop-up message boxes or other visible activity during the connection attempt.
  4. It is somewhat weird that you are connecting to a host named DiscoveryServer, with just a port name and no path in the URL (although in principle it is possible; and common with embedded UA servers). Can you disclose what OPC UA server (vendor, protocol, product name, version...) you are connecting to?

One more thing: Apparently you still use "xxx" and "yyy" as username and password in the UAEndpointDescriptor. As I described earlier, this is normally not used with OPC UA. Unless you really know what you are doing and why need (and you also use it the same way with other OPC clients), remove it, and only keep the username and password in the UserIdentity.

Best regards
Last edit: 15 Oct 2014 13:38 by support.
The following user(s) said Thank You: g.aino

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

More
15 Oct 2014 10:25 #2435 by g.aino
Hello,
thanks for your answer. We set SecurityMode as suggested with some little corrections on previous initialization parts, now authentication seems working.

We tried to read a node value but it produces a Timeout Exception (same error with "easyUAClient.BrowseDataNodes(...)"). Solution seems easy, but we can't figured out until now.

Below the code:
private static void test2()
{
	string strUri = "opc.tcp://DiscoveryServer:4841";
 
	EasyUAClient.LogEntry += EasyUAClient_LogEntry;
 
	// Instantiate the client object
	EasyUAClient easyUAClient = new EasyUAClient()
	{
		Isolated = true,
		IsolatedParameters =
		{
			Session =
			{
				CertificateAcceptancePolicy = { AcceptAnyCertificate = true, AllowUserAcceptCertificate = false },                            
				EndpointSelectionPolicy =
				{
					AllowedMessageSecurityModes = UAMessageSecurityModes.SecurityNone, //<-- As suggested OK!
				},
				UserIdentity =
				{
					UserNameToken = { UserName = "xxx", Password = "yyy" }
				},
 
				SelectBestEndpoint = true,
				//HoldPeriod = 60000   
			},
		},
	};
 
	UAEndpointDescriptor uaEndpointDescriptor = new UAEndpointDescriptor(strUri) { UserName = "xxx", Password = "yyy" };
 
	// Obtain data nodes under "Objects" node
	try
	{
		//UANodeElementCollection nodeElementCollection = easyUAClient.BrowseDataNodes(uaEndpointDescriptor); //<-- Also this throws timeout exception
		string res = easyUAClient.ReadValue(uaEndpointDescriptor, new UANodeDescriptor(			"ns=2;s=TESTFolder/IMO2222222/MasterData/ApparelId/Name")).ToString(); // <--- timeout exception
		m_logHistory += string.Format("result='{0}'", res);
		Console.WriteLine(res);
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message));
	}
}

We also attach the log file, made hooking the EasyUAClient.LogEntry event as you suggested.

File Attachment:

File Name: Log_test_O...5050.txt
File Size:4 KB



Thanks in advance
Attachments:

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

More
14 Oct 2014 16:28 #2433 by support
The way to figure out precisely which endpoints have been returned by the server, and how they have been evaluated against the endpoint selection policy, would be to hook to the static EasyUAClient.LogEntry event, and record the events generated. One of them will contain a "report" which lists the endpoints and whether/why they have been chosen/not chosen.

But. I think I know the reason already. You have AllowedMessageSecurityModes = UAMessageSecurityModes.None, which means that NO security modes are allowed - therefore it will always fail. You probably wanted to use AllowedMessageSecurityModes = UAMessageSecurityModes.SecurityNone instead (or, to allow all modes, use AllowedMessageSecurityModes = UAMessageSecurityModes.All). The enumeration is defined as follows (shortened):
    /// <summary>
    /// Specifies what security should be applied to messages exchanges during a Session.
    /// </summary>
    [Description("Specifies what security should be applied to messages exchanges during a Session.")]
    [Flags]
    public enum UAMessageSecurityModes
    {
        /// <summary>
        /// No security mode is specified.
        /// </summary>
        [Description("No security mode is specified.")]
        None = 0,
 
        /// <summary>
        /// No security is applied.
        /// </summary>
        [Description("No security is applied.")]
        SecurityNone = 1,
 
        /// <summary>
        /// All messages are signed but not encrypted.
        /// </summary>
        [Description("All messages are signed but not encrypted.")]
        SecuritySign = 2,
 
        /// <summary>
        /// All messages are signed and encrypted.
        /// </summary>
        [Description("All messages are signed and encrypted.")]
        SecuritySignAndEncrypt = 4,
 
        /// <summary>
        /// Any mode that is secure.
        /// </summary>
        [Description("Any mode that is secure.")]
        Secure = SecuritySign | SecuritySignAndEncrypt,
 
        /// <summary>
        /// All possible security modes, including no security.
        /// </summary>
        [Description("All possible security modes, including no security.")]
        All = SecurityNone | SecuritySign | SecuritySignAndEncrypt,
    }
 
The following user(s) said Thank You: g.aino

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

More
14 Oct 2014 09:15 #2432 by g.aino
Hi,
first of all thanks for your quick answers. I tried to connect my server as you suggested, but I get the following InnerException, wrapped in the standard "An unhandled exception of type 'OpcLabs.EasyOpc.UA.UAException' occurred in OpcLabs.EasyOpcUA.dll":

"Cannot select the best (any) endpoint for OPC-UA client session. No suitable endpoint has been found. The server returned 5 endpoints.\r\n There are several configurable settings that influence which endpoints are eligible for selection, such as the endpoint selection policy, and also parameters that influence how thorough checks of the information returned by the server are made. You may need to change the endpoint selection policy, or the additional parameters, in order to be able to connect. If you are unsure about what is causing all endpoints to be rejected, analyze the log entries generated by the component."


Trying to connect with UA Sample Client (under Start -> OPC Foundation-> UA SDK 1.01 -> Testing), I'm connecting with following parameters (see image below):

I'm pointing off that I'm allowed to choose any SecurityMode and SecurityPolicy, but the only one works at the moment is the default (None - None - Binary).

Below the code we are using (previous trials we have done are commented)
string strUri = "opc.tcp://DiscoveryServer:4841";
// Instantiate the client object
EasyUAClient easyUAClient = new EasyUAClient()
{
	Isolated = true,
	IsolatedParameters =
	{
		//Discovery = { CheckApplicationDescription = true, DiscoveryTimeout = 10000 },
		//Host = { ParallelDiscovery = true, DiscoveryUriTemplateStrings = new string[] { strUri }, ParallelDiscovery = false },
		Session =
		{
			//CertificateAcceptancePolicy = { AcceptAnyCertificate = false, AllowUserAcceptCertificate = true },
			EndpointSelectionPolicy =
			{
				AllowedMessageSecurityModes = UAMessageSecurityModes.None,
				//AllowZeroSecurityLevel = true,
				//MessageSecurityPreference = OpcLabs.BaseLib.Sign.None
			},
			UserIdentity =
			{
				UserNameToken = { UserName = "xxx", Password = "yyy" }
			},
			//AllowEndpointDomainPrompt = false,
			//CheckEndpointDomain = false,
			//DiagnosticsMasks = UADiagnosticsMasks.All,
			//SelectBestEndpoint = true,
			//UpdateEndpointBeforeConnect = true
		}
	},
	//InstanceParameters =
	//{
	//    DiscoveryHost = strUri,
	//    Mode = EasyUAClientMode.Default
	//}
};
UAEndpointDescriptor uaEndpointDescriptor = new UAEndpointDescriptor(strUri);
UANodeElementCollection nodeElementCollection = easyUAClient.BrowseDataNodes(uaEndpointDescriptor);

I think our configuration matches many allowed policies, so returned endpoints are more than one (5 in error message) and the client isn't able to choose the right for us.

Does it exists a configuration (or a method call) can solve this problem?

Thanks in advance,
Giuseppe
Attachments:

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

More
13 Oct 2014 16:31 #2429 by support
Since you have mentioned your final intent to subscribe to data changes, here is an example (again, from the mentioned solution) that does it.

// This example shows how to subscribe to changes of multiple monitored items and display the value of the monitored item with 
// each change.
using OpcLabs.EasyOpc.UA;
using System;
 
namespace UADocExamples
{
    namespace _EasyUAClient
    {
        class SubscribeMultipleMonitoredItems
        {
            public static void Overload1()
            {
                // Instantiate the client object and hook events
                var easyUAClient = new EasyUAClient();
                easyUAClient.MonitoredItemChanged += easyUAClient_MonitoredItemChanged;
 
                Console.WriteLine("Subscribing...");
                easyUAClient.SubscribeMultipleMonitoredItems(new[]
                    {
                        new EasyUAMonitoredItemArguments(null, "http://localhost:51211/UA/SampleServer", 
                            "nsu=http://test.org/UA/Data/;i=10845", 1000),
                        new EasyUAMonitoredItemArguments(null, "http://localhost:51211/UA/SampleServer", 
                            "nsu=http://test.org/UA/Data/;i=10853", 1000),
                        new EasyUAMonitoredItemArguments(null, "http://localhost:51211/UA/SampleServer", 
                            "nsu=http://test.org/UA/Data/;i=10855", 1000)
                    });
 
                Console.WriteLine("Processing monitored item changed events for 10 seconds...");
                System.Threading.Thread.Sleep(10 * 1000);
 
                Console.WriteLine("Unsubscribing...");
                easyUAClient.UnsubscribeAllMonitoredItems();
 
                Console.WriteLine("Waiting for 5 seconds...");
                System.Threading.Thread.Sleep(5 * 1000);
            }
 
            static void easyUAClient_MonitoredItemChanged(object sender, EasyUAMonitoredItemChangedEventArgs e)
            {
                // Display value
                // Remark: Production code would check e.Exception before accessing e.AttributeData.
                Console.WriteLine("{0}: {1}", e.Arguments.NodeDescriptor, e.AttributeData.Value);
            }
        }
    }
}

If you want to write something like a Web service, you will have to resolve somehow how to transform this event-driven approach (where data come in at any moment) to a model where it is the Web service consumer that asks for them actively. However anything in this area highly depends on your requirements which I do not know in detail at the moment.

Best regards

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

More
13 Oct 2014 16:23 #2428 by support
The UserName and Password on the UAEndpointDescriptor have a different purpose (in short, they are not normally used). If you want to authenticate the user using his name and password (and not through a certificate as originally requested), create the EasyUAClient like this:
var client = new EasyUAClient
{
     Isolated = true,
     IsolatedParameters = 
     { 
         Session = { UserIdentity = { UserNameToken = { UserName = "usr", Password = "pwd" }}}
     }
};

Best regards
The following user(s) said Thank You: g.aino

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

More
13 Oct 2014 16:10 #2427 by g.aino
Thank you very much for your reply. Sorry if I didn't specify that I use C#.
To send user information to the server I customize the code sample as follow:
// Instantiate the client object
var easyUAClient = new EasyUAClient();
 
// Obtain nodes under "Server" node
string strUri = "opc.tcp://subDomain.domain.it:9999";
 
UAEndpointDescriptor endPointDescription = new UAEndpointDescriptor(strUri)
{
	UserName = "myUser",
	Password = "xxx"
};
 
UANodeElementCollection nodeElementCollection = easyUAClient.BrowseNodes(
	endPointDescription,
	UAObjectIds.Server,
	new UABrowseParameters(UANodeClass.All, new[] { UAReferenceTypeIds.References }));
 
// Display results


but I get this error:
Message: OPC-UA service result - Endpoint does not supported the user identity type provided. .....
ServiceResult: {BadUserAccessDenied}

I suppose is also because I didn't specify the: "Security mode, policy and Encoding", how can send this info before the
easyUAClient.BrowseNodes(...
?

Thank you

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

More
13 Oct 2014 15:56 #2426 by support
This post: www.opclabs.com/forum/ua-connections/1447-specifying-security-policy-user-name-and-password answers the part about security modes, and also gives some insight into user authentication, although in that post it explains how to use a username/password token.

For user authentication with a certificate.

     var client = new EasyUAClient
     {
          Isolated = true,
          IsolatedParameters =
          {
               Session = { UserIdentity = 
                   { 
                        X509CertificateToken = { FileName = "...", Password = "..." } 
                   }
               }
          }
      };
The following user(s) said Thank You: g.aino

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

More
13 Oct 2014 15:43 #2425 by support
Ad

1. Set server (NOT localhost and standard demo configuration) address/ endpoint like opc.tcp://yyyy.zzz.xx:9999


I believe this is already demonstrated in the browsing example - the endpoint URL can be passed as first parameter to most our methods (it implicitly converts to UAEndpointDescriptor which contains all the details). For example, with subscriptions:
 easyUAClient.SubscribeMonitoredItem(
                    "http://localhost:51211/UA/SampleServer",
                    "nsu=http://test.org/UA/Data/;i=10853",
                    1000);

Note that our API is connectionless - you do not explicitly open and close connections, that is taken care of internally for you.
The following user(s) said Thank You: g.aino

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

More
13 Oct 2014 15:36 #2424 by support
I will answer this in parts - this post is about the basic UA browsing example. There will be separate posts about your other questions.

You can find examples of code-based (i.e. not a user interface) UA browsing in the C# examples solution, installed with the product and available from the Start menu. When you open that solution in Visual Studio, and navigate (in Solution Explorer) under Console/UADocExamples, you can pick e.g. the _EasyUAClient.BrowseNodes.Main.cs file; the core of the example looks like this:
// Shows how to obtain references of all kinds to nodes of all classes, from the "Server" node in the address space.
using System;
using System.Diagnostics;
using OpcLabs.EasyOpc.UA;
 
namespace UADocExamples
{
    namespace _EasyUAClient
    {
        class BrowseNodes
        {
            public static void Main()
            {
                // Instantiate the client object
                var easyUAClient = new EasyUAClient();
 
                // Obtain nodes under "Server" node
                UANodeElementCollection nodeElementCollection = easyUAClient.BrowseNodes(
                    "http://localhost:51211/UA/SampleServer", // or "opc.tcp://localhost:51210/UA/SampleServer"
                    UAObjectIds.Server,
                    new UABrowseParameters(UANodeClass.All, new [] { UAReferenceTypeIds.References } ));
 
                // Display results
                foreach (UANodeElement nodeElement in nodeElementCollection)
                {
                    Debug.Assert(nodeElement != null);
                    Console.WriteLine();
                    Console.WriteLine("nodeElement.NodeId: {0}", nodeElement.NodeId);
                    Console.WriteLine("nodeElement.DisplayName: {0}", nodeElement.DisplayName);
                }
            }
        }
    }
}

Other neighboring files show different browsing methods, such as BrowseVariables, BrowseObjects, etc. There is also a corresponding example in VB.NET in a separate solution with Visual Basic projects.

Note that there is no "single" starting node (no root) in OPC UA. Here we are starting with the "Server" node (UAObjectIds.Server); it would be more typical to start with UAObjectIds.Objects, but really that depends on your needs.

Best regards
The following user(s) said Thank You: g.aino

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

Moderators: support
Time to create page: 0.077 seconds