9.3 KiB
using Opc.Ua; using Opc.Ua.Client; using Opc.Ua.Configuration; using System.Security.Cryptography.X509Certificates;
namespace OpcConnectionTest
{
class Program
{
[Obsolete]
static async Task Main(string[] args)
{
Console.WriteLine("= Experion OPC UA Connection Test =\n");
// ⚠️ Experion 서버 IP 주소 수정 string endpoint = "opc.tcp://192.168.0.20:4840"; string pfxPath = Path.Combine(Directory.GetCurrentDirectory(), "pki/own/certs/OpcTestClient.pfx"); X509Certificate2 clientCertificate = new X509Certificate2(pfxPath, "");
Console.WriteLine($"Server: {endpoint}\n");
ISession? session = null;
try { // 1. Configuration 생성 var config = new ApplicationConfiguration() { ApplicationName = "OPC Test Client", ApplicationType = ApplicationType.Client, ApplicationUri = "urn:OpcTestClient",
SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { StoreType = "Directory", StorePath = Path.GetFullPath("pki/own"), SubjectName = "CN=OpcTestClient" },
TrustedPeerCertificates = new CertificateTrustList { StoreType = "Directory", StorePath = Path.GetFullPath("pki/trusted") },
TrustedIssuerCertificates = new CertificateTrustList { StoreType = "Directory", StorePath = Path.GetFullPath("pki/issuers") },
RejectedCertificateStore = new CertificateTrustList { StoreType = "Directory", StorePath = Path.GetFullPath("pki/rejected") },
AutoAcceptUntrustedCertificates = true, RejectSHA1SignedCertificates = false, AddAppCertToTrustedStore = true },
TransportConfigurations = new TransportConfigurationCollection(), TransportQuotas = new TransportQuotas { OperationTimeout = 15000 }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 } };
await config.ValidateAsync(ApplicationType.Client);
Console.WriteLine("Step 1: Discovering endpoints…");
// 2. Endpoint 검색 var endpointConfig = EndpointConfiguration.Create(config); endpointConfig.OperationTimeout = 10000;
var discoveryClient = await DiscoveryClient.CreateAsync( new Uri(endpoint), endpointConfig, config, DiagnosticsMasks.None, CancellationToken.None);
var endpoints = await discoveryClient.GetEndpointsAsync(null); discoveryClient.Dispose();
if (endpoints = null || endpoints.Count = 0)
{
Console.WriteLine("❌ No endpoints found!");
return;
}
Console.WriteLine($"✅ Found {endpoints.Count} endpoint(s)"); foreach (var ep in endpoints) { Console.WriteLine($" - {ep.EndpointUrl} ({ep.SecurityMode})"); }
Console.WriteLine("\nStep 2: Creating session…");
// 3. ConfiguredEndpoint 생성 var selectedEndpoint = endpoints[0]; var configuredEndpoint = new ConfiguredEndpoint( null, selectedEndpoint, EndpointConfiguration.Create(config));
// Session.Create 호출 직전에 추가 var cert = await config.SecurityConfiguration.ApplicationCertificate.Find(true); if (cert == null) { Console.WriteLine("❌ [Internal Error] 코드가 인증서 파일을 찾지 못했습니다!"); Console.WriteLine($"확인 경로: {Path.GetFullPath(config.SecurityConfiguration.ApplicationCertificate.StorePath)}"); return; } else { Console.WriteLine($"✅ 인증서 로드 성공: {cert.Subject}"); }
// 4. Session 생성 (최신 API) session = await Session.Create( config, configuredEndpoint, false, "OPC Test Session", 60000, new UserIdentity(new AnonymousIdentityToken()), null);
Console.WriteLine($"✅ Connected!"); Console.WriteLine($" Session ID: {session.SessionId}");
Console.WriteLine("\nStep 3: Reading server info…"); await ReadServerInfoAsync(session);
Console.WriteLine("\nStep 4: Checking redundancy…"); await CheckRedundancyAsync(session);
Console.WriteLine("\nStep 5: Browsing nodes…"); await BrowseNodesAsync(session);
Console.WriteLine("\n✅ All tests completed!"); } catch (Exception ex) { Console.WriteLine($"\n❌ Error: {ex.Message}"); Console.WriteLine($"Type: {ex.GetType().Name}");
if (ex.InnerException != null) { Console.WriteLine($"Inner: {ex.InnerException.Message}"); } } finally { if (session != null) { try { Console.WriteLine("\nClosing session…"); await session.CloseAsync(); session.Dispose(); Console.WriteLine("✅ Session closed"); } catch { } } }
Console.WriteLine("\nPress Enter to exit…"); Console.ReadLine(); }
static async Task ReadServerInfoAsync(ISession session) { try { // Server State var state = await session.ReadValueAsync( new NodeId(Variables.Server_ServerStatus_State)); Console.WriteLine($" State: {state.Value}");
// Server Time var time = await session.ReadValueAsync( new NodeId(Variables.Server_ServerStatus_CurrentTime)); Console.WriteLine($" Time: {time.Value}"); } catch (Exception ex) { Console.WriteLine($" Error: {ex.Message}"); } }
static async Task CheckRedundancyAsync(ISession session) { try { var serviceLevel = await session.ReadValueAsync( new NodeId(Variables.Server_ServiceLevel));
byte level = Convert.ToByte(serviceLevel.Value); Console.WriteLine($" Service Level: {level}");
if (level >= 200) Console.WriteLine(" ✅ PRIMARY server"); else if (level > 0) Console.WriteLine(" ⚠️ SECONDARY server"); else Console.WriteLine(" ℹ️ STANDALONE"); } catch (Exception ex) { Console.WriteLine($" Error: {ex.Message}"); } }
static async Task BrowseNodesAsync(ISession session) { try { var browser = new Browser(session) { BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences, IncludeSubtypes = true, NodeClassMask = (int)(NodeClass.Object | NodeClass.Variable) };
var references = await browser.BrowseAsync(ObjectIds.ObjectsFolder);
Console.WriteLine($" Found {references.Count} top-level nodes:");
int count = 0; foreach (var r in references) { Console.WriteLine($" {r.DisplayName} ({r.NodeClass})"); if (++count >= 5) { Console.WriteLine($" … and {references.Count - 5} more"); break; } } } catch (Exception ex) { Console.WriteLine($" Error: {ex.Message}"); } } } }