/* ======================================================================== * Copyright (c) 2005-2021 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ * ======================================================================*/ using System; using System.Globalization; using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Opc.Ua; using Opc.Ua.Configuration; namespace Quickstarts.ConsoleReferenceClient { /// /// The program. /// public static class Program { /// /// Main entry point. /// public static async Task Main(string[] args) { TextWriter output = Console.Out; output.WriteLine("OPC UA Console Reference Client"); output.WriteLine("OPC UA library: {0} @ {1} -- {2}", Utils.GetAssemblyBuildNumber(), Utils.GetAssemblyTimestamp().ToString("G", CultureInfo.InvariantCulture), Utils.GetAssemblySoftwareVersion()); // The application name and config file names var applicationName = "ConsoleReferenceClient"; var configSectionName = "Quickstarts.ReferenceClient"; var usage = $"Usage: dotnet {applicationName}.dll [OPTIONS]"; // command line options bool showHelp = false; bool autoAccept = false; bool logConsole = false; bool appLog = false; bool renewCertificate = false; string password = null; int timeout = Timeout.Infinite; Mono.Options.OptionSet options = new Mono.Options.OptionSet { usage, { "h|help", "show this message and exit", h => showHelp = h != null }, { "a|autoaccept", "auto accept certificates (for testing only)", a => autoAccept = a != null }, { "c|console", "log to console", c => logConsole = c != null }, { "l|log", "log app output", c => appLog = c != null }, { "p|password=", "optional password for private key", (string p) => password = p }, { "r|renew", "renew application certificate", r => renewCertificate = r != null }, { "t|timeout=", "timeout in seconds to exit application", (int t) => timeout = t * 1000 }, }; try { // parse command line and set options var extraArg = ConsoleUtils.ProcessCommandLine(output, args, options, ref showHelp, false); // connect Url? Uri serverUrl = new Uri("opc.tcp://localhost:62541/Quickstarts/ReferenceServer"); if (!string.IsNullOrEmpty(extraArg)) { serverUrl = new Uri(extraArg); } // log console output to logger if (logConsole && appLog) { output = new LogWriter(); } // Define the UA Client application ApplicationInstance.MessageDlg = new ApplicationMessageDlg(output); CertificatePasswordProvider PasswordProvider = new CertificatePasswordProvider(password); ApplicationInstance application = new ApplicationInstance { ApplicationName = applicationName, ApplicationType = ApplicationType.Client, ConfigSectionName = configSectionName, CertificatePasswordProvider = PasswordProvider }; // load the application configuration. var config = await application.LoadApplicationConfiguration(silent: false); // setup the logging ConsoleUtils.ConfigureLogging(config, applicationName, logConsole, LogLevel.Information); // delete old certificate if (renewCertificate) { await application.DeleteApplicationInstanceCertificate().ConfigureAwait(false); } // check the application certificate. bool haveAppCertificate = await application.CheckApplicationInstanceCertificate(false, minimumKeySize: 0).ConfigureAwait(false); if (!haveAppCertificate) { throw new ErrorExitException("Application instance certificate invalid!", ExitCode.ErrorCertificate); } // wait for timeout or Ctrl-C var quitEvent = ConsoleUtils.CtrlCHandler(); // connect to a server until application stopped bool quit = false; DateTime start = DateTime.UtcNow; int waitTime = int.MaxValue; do { if (timeout > 0) { waitTime = timeout - (int)DateTime.UtcNow.Subtract(start).TotalMilliseconds; if (waitTime <= 0) { break; } } // create the UA Client object and connect to configured server. UAClient uaClient = new UAClient(application.ApplicationConfiguration, output, ClientBase.ValidateResponse) { AutoAccept = autoAccept }; bool connected = await uaClient.ConnectAsync(serverUrl.ToString()); if (connected) { // Run tests for available methods. uaClient.ReadNodes(); uaClient.WriteNodes(); uaClient.Browse(); uaClient.CallMethod(); uaClient.SubscribeToDataChanges(); // Wait for some DataChange notifications from MonitoredItems quit = quitEvent.WaitOne(Math.Min(30_000, waitTime)); uaClient.Disconnect(); } else { output.WriteLine("Could not connect to server! Retry in 10 seconds or Ctrl-C to quit."); quit = quitEvent.WaitOne(Math.Min(10_000, waitTime)); } } while (!quit); output.WriteLine("\nClient stopped."); } catch (Exception ex) { output.WriteLine(ex.Message); } } } }