Anleitung
Konfiguration
Den Client konfigurieren: Anwendung, Verbindungsüberwachung, Grenzen der Datenübertragung, Zertifikat und XML-Konfiguration.
Anleitung
Konfiguration
Anwendung und Sitzung konfigurieren
Beteiligte TypenOpcClientOpcApplicationConfigurationOpcCertificateStoresOpcCertificateStoreInfo
Alle Codeausschnitte auf dieser Seite konfigurieren den Client im Code, sofern er nicht mit seiner Standardkonfiguration arbeitet. Zentrale Stelle für die Konfiguration der Clientanwendung, der Sitzungsparameter und der Verbindungsparameter ist die Instanz von OpcClient. Alle Sicherheitseinstellungen liefert die Eigenschaft Security des Clients als Instanz der Klasse OpcClientSecurity. Alle Einstellungen der Zertifikatspeicher liefert die Eigenschaft CertificateStores des Clients als Instanz der Klasse OpcCertificateStores.
Wenn der Client auch per XML konfigurierbar sein soll, laden Sie seine Konfiguration aus einer XML-Datei. Wie die Datei aufgebaut ist, zeigt der Abschnitt Konfiguration per XML-Datei. So laden Sie die Einstellungen:
Konfigurationsdatei über den Namen der Konfiguration laden: Die Methode LoadClientConfig sucht im Arbeitsverzeichnis der Anwendung die Datei <Name>.Config.xml, im folgenden Beispiel also Opc.UaFx.Client.Config.xml.
client.Configuration = OpcApplicationConfiguration.LoadClientConfig("Opc.UaFx.Client");client.Configuration = OpcApplicationConfiguration.LoadClientConfig("Opc.UaFx.Client")Konfigurationsdatei über den Pfad zur XML-Datei laden: Wenn die Datei fehlt oder nicht lesbar ist, lösen LoadClientConfig und LoadClientConfigFile keine Ausnahme aus, sondern liefern null. Prüfen Sie deshalb den Rückgabewert:
var configuration = OpcApplicationConfiguration.LoadClientConfigFile("MyClientAppNameConfig.xml");
// The method returns a null reference in case the file could not be loaded.
if (configuration == null)
throw new InvalidOperationException("The client configuration could not be loaded.");
client.Configuration = configuration;Dim configuration = OpcApplicationConfiguration.LoadClientConfigFile("MyClientAppNameConfig.xml")
'The method returns Nothing in case the file could not be loaded.
If configuration Is Nothing Then
Throw New InvalidOperationException("The client configuration could not be loaded.")
End If
client.Configuration = configurationFür die Konfiguration der Clientanwendung gibt es unter anderem die folgenden Einstellungen:
Anwendung konfigurieren (per Code): Ohne Angabe verwendet der Client als ApplicationName den Wert des Attributs AssemblyTitle, ersatzweise den des Attributs AssemblyProduct und sonst OPC Application. Die ApplicationUri übernimmt der Client aus dem Anwendungszertifikat (Subject Alternative Name) und überschreibt dabei einen im Code festgelegten Wert. Den Wert aus dem Code verwendet er nur, wenn er ein neues Anwendungszertifikat erzeugt. Fehlt auch dieser Wert, gilt urn:<Hostname>:<ApplicationName>.
// Default: Value of AssemblyTitleAttribute of entry assembly.
client.ApplicationName = "MyClientAppName";
// Default: A null reference to use the URI of the application certificate.
// The value is used to create a new application certificate.
client.ApplicationUri = new Uri("urn:localhost:MyClientAppName");'Default: Value of AssemblyTitleAttribute of entry assembly.
client.ApplicationName = "MyClientAppName"
'Default: Nothing to use the URI of the application certificate.
'The value is used to create a new application certificate.
client.ApplicationUri = New Uri("urn:localhost:MyClientAppName")Per XML (unterhalb des Elements OpcApplicationConfiguration):
<ApplicationName>MyClient Configured via XML</ApplicationName>
<ApplicationUri>http://myclient/application</ApplicationUri>Sitzungsparameter konfigurieren (per Code): Ohne SessionName erhält die Sitzung den Namen der Anwendung (ApplicationName).
client.SessionTimeout = 30000; // Default: 60000
client.SessionName = "My Session Name"; // Default: Value of ApplicationNameclient.SessionTimeout = 30000 'Default: 60000
client.SessionName = "My Session Name" 'Default: Value of ApplicationNamePer XML (unterhalb des Elements OpcApplicationConfiguration). Der Client verwendet den Wert aus der XML-Datei nur, wenn seine Eigenschaft SessionTimeout auf 0 gesetzt ist:
<DefaultSessionTimeout>600000</DefaultSessionTimeout>Verbindungsparameter konfigurieren (per Code): Die Eigenschaft OperationTimeout legt fest, wie lange der Client höchstens auf die Antwort einer Anfrage wartet (standardmäßig 120000 Millisekunden).
client.OperationTimeout = 10000; // Default: 120000
client.DisconnectTimeout = 5000; // Default: 10000
client.ReconnectInterval = 5000; // Default: 10000client.OperationTimeout = 10000 'Default: 120000
client.DisconnectTimeout = 5000 'Default: 10000
client.ReconnectInterval = 5000 'Default: 10000Per XML (unterhalb des Elements OpcApplicationConfiguration):
<OperationTimeout>120000</OperationTimeout>Zertifikatspeicher konfigurieren (per Code): Standardmäßig liegen die Zertifikatspeicher im Ordner CertificateStores im Verzeichnis der Anwendung. Wenn dieses Verzeichnis nicht beschreibbar ist, verwendet der Client den Ordner OPC Foundation\CertificateStores unterhalb von %ProgramData% beziehungsweise %AppData%. Die Reihenfolge der geprüften Pfade lässt sich über die Eigenschaft OpcCertificateStores.PathProbings anpassen.
// Default: ".\CertificateStores\App"
client.CertificateStores.ApplicationStore.Path
= @"%LocalApplicationData%\MyClientAppName\App Certificates";
// Default: ".\CertificateStores\Rejected"
client.CertificateStores.RejectedStore.Path
= @"%LocalApplicationData%\MyClientAppName\Rejected Certificates";
// Default: ".\CertificateStores\Trusted"
client.CertificateStores.TrustedIssuerStore.Path
= @"%LocalApplicationData%\MyClientAppName\Trusted Issuer Certificates";
// Default: ".\CertificateStores\Trusted"
client.CertificateStores.TrustedPeerStore.Path
= @"%LocalApplicationData%\MyClientAppName\Trusted Peer Certificates";'Default: ".\CertificateStores\App"
client.CertificateStores.ApplicationStore.Path _
= "%LocalApplicationData%\MyClientAppName\App Certificates"
'Default: ".\CertificateStores\Rejected"
client.CertificateStores.RejectedStore.Path _
= "%LocalApplicationData%\MyClientAppName\Rejected Certificates"
'Default: ".\CertificateStores\Trusted"
client.CertificateStores.TrustedIssuerStore.Path _
= "%LocalApplicationData%\MyClientAppName\Trusted Issuer Certificates"
'Default: ".\CertificateStores\Trusted"
client.CertificateStores.TrustedPeerStore.Path _
= "%LocalApplicationData%\MyClientAppName\Trusted Peer Certificates"Per XML (unterhalb des Elements OpcApplicationConfiguration):
<SecurityConfiguration>
<ApplicationCertificate>
<StoreType>Directory</StoreType>
<StorePath>.\CertificateStores\App</StorePath>
<SubjectName>CN=MyClient, C=US, S=Arizona, O=YourCompany, DC=localhost</SubjectName>
<!-- <Thumbprint>3a35fb798fc6dee8a7e7e4652b0e28fc14c6ee0f</Thumbprint> -->
</ApplicationCertificate>
<TrustedIssuerCertificates>
<StoreType>Directory</StoreType>
<StorePath>.\CertificateStores\Trusted</StorePath>
</TrustedIssuerCertificates>
<TrustedPeerCertificates>
<StoreType>Directory</StoreType>
<StorePath>.\CertificateStores\Trusted</StorePath>
</TrustedPeerCertificates>
<RejectedCertificateStore>
<StoreType>Directory</StoreType>
<StorePath>.\CertificateStores\Rejected</StorePath>
</RejectedCertificateStore>
</SecurityConfiguration>Bevorzugte Sprachen der Sitzung festlegen: Über Locales teilt der Client dem Server mit, in welchen Sprachen er Texte wie DisplayName, Description und Ereignismeldungen bevorzugt erhalten möchte. Der Client übergibt die Sprachen beim Erstellen der Sitzung. Ohne Angabe liefert der Server seine Standardsprache.
client.Locales.Add("de-DE");
client.Locales.Add("en-US");
client.Connect();
OpcValue displayName = client.ReadNode("ns=2;s=Machine", OpcAttribute.DisplayName);client.Locales.Add("de-DE")
client.Locales.Add("en-US")
client.Connect()
Dim displayName As OpcValue = client.ReadNode("ns=2;s=Machine", OpcAttribute.DisplayName)Verbindungsüberwachung
Beteiligte TypenOpcClientOpcClientKeepAlive
Wie der Client Verbindungsabbrüche erkennt und die Verbindung wiederherstellt, beschreibt der Abschnitt Verbindungsabbrüche erkennen der Einführung. Die folgenden Eigenschaften legen das Verhalten fest. Wenn die Eigenschaft ReconnectInterval den Wert 0 hat, stellt der Client die Verbindung nicht wieder her, sondern löst das Ereignis BreakDetected aus. Die Eigenschaft MaxReconnectDuration begrenzt, wie lange der Client es versucht (standardmäßig 0, unbegrenzt):
client.UseBreakDetection = true; // Default: true
client.KeepAlive.Interval = 2000; // Default: 5000
client.ReconnectInterval = 5000; // Default: 10000
client.MaxReconnectDuration = 0; // Default: 0 (unlimited)client.UseBreakDetection = True 'Default: True
client.KeepAlive.Interval = 2000 'Default: 5000
client.ReconnectInterval = 5000 'Default: 10000
client.MaxReconnectDuration = 0 'Default: 0 (unlimited)Auf Verbindungsabbrüche reagieren: Wenn der Client nach einem Abbruch eine neue Sitzung erstellt hat, löst er statt Reconnected das Ereignis Connected aus.
client.Reconnecting += HandleReconnecting;
client.Reconnected += HandleReconnected;
client.BreakDetected += HandleBreakDetected;
...
private static void HandleReconnecting(object sender, EventArgs e)
{
Console.WriteLine("Connection lost, trying to reconnect.");
}
private static void HandleReconnected(object sender, EventArgs e)
{
Console.WriteLine("Connection restored using the existing session.");
}
private static void HandleBreakDetected(object sender, EventArgs e)
{
Console.WriteLine("Connection lost, no automatic reconnect.");
}AddHandler client.Reconnecting, AddressOf HandleReconnecting
AddHandler client.Reconnected, AddressOf HandleReconnected
AddHandler client.BreakDetected, AddressOf HandleBreakDetected
...
Private Shared Sub HandleReconnecting(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("Connection lost, trying to reconnect.")
End Sub
Private Shared Sub HandleReconnected(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("Connection restored using the existing session.")
End Sub
Private Shared Sub HandleBreakDetected(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("Connection lost, no automatic reconnect.")
End SubDas Ergebnis der KeepAlive-Anfragen auswerten:
client.KeepAlive.Updated += HandleKeepAliveUpdated;
...
private static void HandleKeepAliveUpdated(object sender, EventArgs e)
{
OpcClientKeepAlive keepAlive = (OpcClientKeepAlive)sender;
if (keepAlive.IsActive) {
Console.WriteLine(
"Server state: {0}, server time: {1}",
keepAlive.ServerState,
keepAlive.Time);
}
else {
Console.WriteLine("Keep alive failed: {0}", keepAlive.Status);
}
}AddHandler client.KeepAlive.Updated, AddressOf HandleKeepAliveUpdated
...
Private Shared Sub HandleKeepAliveUpdated(ByVal sender As Object, ByVal e As EventArgs)
Dim keepAlive As OpcClientKeepAlive = CType(sender, OpcClientKeepAlive)
If keepAlive.IsActive Then
Console.WriteLine( _
"Server state: {0}, server time: {1}", _
keepAlive.ServerState, _
keepAlive.Time)
Else
Console.WriteLine("Keep alive failed: {0}", keepAlive.Status)
End If
End SubWas der Client bei einem Abbruch selbst übernimmt und was die Anwendung im Dauerbetrieb beachten sollte, beschreibt die Seite Clients für den Dauerbetrieb.
Grenzen der Datenübertragung
Beteiligte TypenOpcClientOpcTransport
Der Client begrenzt die Größe der Daten, die er mit dem Server austauscht. Wenn ein Wert eine dieser Grenzen überschreitet, schlägt das Dekodieren fehl, zum Beispiel mit dem Status BadEncodingLimitsExceeded. Wenn Sie große Zeichenketten, Arrays oder Strukturen übertragen, erhöhen Sie die Grenzen über die Eigenschaft Transport des Clients:
client.Transport.MaxStringLength = 1048576; // Default: 65535
client.Transport.MaxByteStringLength = 10485760; // Default: 5242880
client.Transport.MaxArrayLength = 1000000; // Default: 65535
client.Transport.MaxMessageSize = 20971520; // Default: 10485760client.Transport.MaxStringLength = 1048576 'Default: 65535
client.Transport.MaxByteStringLength = 10485760 'Default: 5242880
client.Transport.MaxArrayLength = 1000000 'Default: 65535
client.Transport.MaxMessageSize = 20971520 'Default: 10485760Die Werte entsprechen den Einträgen unterhalb des Elements TransportQuotas der XML-Konfiguration. Ebenso teilt der Client große Lese- und Schreibanfragen anhand der vom Server gemeldeten Grenzen automatisch auf mehrere Anfragen auf.
Wie das geschieht und wie sich die Aufteilung beeinflussen lässt, beschreibt der Abschnitt Wie das SDK große Anfragen aufteilt.
Anwendungszertifikat
Beteiligte TypenOpcClientOpcCertificateManagerOpcCertificateSettingsOpcClientSecurityOpcCertificateStoresOpcCertificateStoreInfo
Der Client lädt Zertifikate der Typen .der und .cer (nur der öffentliche Teil) sowie .pfx und .p12 (mit privatem Schlüssel). Wenn der Client einen sicheren Serverendpunkt verwenden soll, muss das Zertifikat einen privaten Schlüssel haben. Sicher ist ein Endpunkt, dessen OpcSecurityMode gleich Sign oder SignAndEncrypt ist.
Ein vorhandenes Zertifikat von einem beliebigen Pfad laden:
var certificate = OpcCertificateManager.LoadCertificate("MyClientCertificate.pfx");Dim certificate = OpcCertificateManager.LoadCertificate("MyClientCertificate.pfx")Ein passwortgeschütztes Zertifikat mit Angabe des Passworts laden:
var certificate = OpcCertificateManager.LoadCertificate(
"MyClientCertificate.pfx",
password: "password");Dim certificate = OpcCertificateManager.LoadCertificate( _
"MyClientCertificate.pfx", _
password:="password")Ein neues Zertifikat im Speicher erzeugen. Wenn Sie dabei Eigenschaften wie die Gültigkeit oder die Domänen festlegen, verwenden Sie die Klasse OpcCertificateSettings (Abschnitt Eigenes Anwendungszertifikat verwenden):
var certificate = OpcCertificateManager.CreateCertificate(client);Dim certificate = OpcCertificateManager.CreateCertificate(client)Das Zertifikat speichern (unter einem beliebigen Pfad):
OpcCertificateManager.SaveCertificate("MyClientCertificate.pfx", certificate);OpcCertificateManager.SaveCertificate("MyClientCertificate.pfx", certificate)Das Clientzertifikat festlegen:
client.Certificate = certificate;client.Certificate = certificateDas Zertifikat muss im Zertifikatspeicher für Anwendungszertifikate (ApplicationStore) gespeichert sein:
if (!client.CertificateStores.ApplicationStore.Contains(certificate))
client.CertificateStores.ApplicationStore.Add(certificate);If Not client.CertificateStores.ApplicationStore.Contains(certificate) Then
client.CertificateStores.ApplicationStore.Add(certificate)
End IfWenn Sie kein Zertifikat festlegen, sucht der Client im ApplicationStore ein Zertifikat, dessen Name dem ApplicationName entspricht. Zuvor löst er das Ereignis CertificateRequested aus, über das die Anwendung selbst ein Zertifikat bereitstellen kann. Wenn der Client kein Zertifikat findet, erzeugt und verwendet er standardmäßig automatisch ein neues Zertifikat. Bis Version 2.58 gilt das auch für ein ungültiges Zertifikat. Ab Version 2.59 behält der Client ein vorhandenes, aber ungültiges Zertifikat und löst das Ereignis CertificateRequested mit dem Grund aus (siehe Eigenes Zertifikat schützen). Wenn auch das fehlschlägt, verwendet er ein temporäres Zertifikat im Speicher. Wenn der Client nur das angegebene Zertifikat verwenden soll, deaktivieren Sie diese Funktion. Setzen Sie dazu die Eigenschaft AutoCreateCertificate auf false:
client.CertificateStores.AutoCreateCertificate = false;client.CertificateStores.AutoCreateCertificate = FalseWie der Client einen sicheren Endpunkt wählt, Serverzertifikate prüft und sich mit einer Benutzeridentität anmeldet, beschreibt die Seite Clients absichern. Dort steht auch, wie Sie den Client für den Produktivbetrieb härten.
Konfiguration per XML-Datei
Wenn der Client auch per XML konfigurierbar sein soll, laden Sie seine Konfiguration aus einer XML-Datei. Die Datei muss dazu den folgenden Standard-XML-Baum aufweisen:
<?xml version="1.0" encoding="utf-8" ?>
<OpcApplicationConfiguration
xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
schemaLocation="AppConfig.xsd">Unterhalb des Elements OpcApplicationConfiguration folgen die Einstellungen aus den vorherigen Abschnitten. Sie laden die Datei auf einem der folgenden Wege:
- über den Pfad zur XML-Datei mit der Methode
LoadClientConfigFile. Die Datei kann einen beliebigen Namen tragen und an einem beliebigen Ort liegen. - über den Namen der Konfiguration mit der Methode
LoadClientConfig. Die Datei muss dann den Namen<Name>.Config.xmltragen (zum BeispielOpc.UaFx.Client.Config.xml) und im Arbeitsverzeichnis der Anwendung liegen.
Beide Methoden liefern null, wenn die Datei fehlt oder nicht lesbar ist (Abschnitt Anwendung und Sitzung konfigurieren). Eine Konfiguration über die App.config der Anwendung (configSections mit einem Verweis auf die XML-Datei) unterstützt das SDK nicht.

