# Configuration

> How-to guide: Configure the client: application, connection monitoring, data transfer limits, certificate, and XML configuration.

> This content was machine translated and may contain errors. [Read in German](https://www.traeger.de/docs/development/opcua/client/configuration)

**Sample applications:**

- Client.ConfiguredViaCode ([C#](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/cs/Configuration/Client.ConfiguredViaCode), [VB.NET](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/vb/Configuration/Client.ConfiguredViaCode)): This sample demonstrates how to configure an OPC UA client using in code configuration.
- Client.ConfiguredViaXml ([C#](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/cs/Configuration/Client.ConfiguredViaXml), [VB.NET](https://github.com/Traeger-GmbH/opcuanet-samples/tree/master/vb/Configuration/Client.ConfiguredViaXml)): This sample demonstrates how to configure an OPC UA client using a XML configuration file.

## Configure the application and session

Types used: `OpcClient`, `OpcApplicationConfiguration`, `OpcCertificateStores`, `OpcCertificateStoreInfo`

All code snippets on this page configure the client in code, unless it works with its default configuration. The `OpcClient` instance is the central place for configuring the client application, the session parameters, and the connection parameters. The client's `Security` property provides all security settings as an instance of the `OpcClientSecurity` class. The client's `CertificateStores` property provides all certificate store settings as an instance of the `OpcCertificateStores` class.

If the client should also be configurable through XML, load its configuration from an XML file. The section [Configuration through an XML file](https://www.traeger.de/en/docs/development/opcua/client/configuration#configuration-through-an-xml-file) shows how the file is structured. To load the settings:

**Load the configuration file by the name of the configuration**: The `LoadClientConfig` method looks for the file `<Name>.Config.xml` in the working directory of the application, in the following example `Opc.UaFx.Client.Config.xml`.

```csharp
client.Configuration = OpcApplicationConfiguration.LoadClientConfig("Opc.UaFx.Client");

```

```vbnet
client.Configuration = OpcApplicationConfiguration.LoadClientConfig("Opc.UaFx.Client")

```

**Load the configuration file by the path to the XML file**: If the file is missing or cannot be read, `LoadClientConfig` and `LoadClientConfigFile` do not throw an exception but return `null`. Check the return value:

```csharp
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;

```

```vbnet
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 = configuration
```

The settings for configuring the client application include the following:

**Configure the application** (in code): If you set no `ApplicationName`, the client uses the value of the `AssemblyTitle` attribute, alternatively that of the `AssemblyProduct` attribute, and otherwise `OPC Application`. The client takes the `ApplicationUri` from the application certificate (Subject Alternative Name) and overrides a value set in code. It uses the value from the code only when it creates a new application certificate. If that value is missing as well, `urn:<Hostname>:<ApplicationName>` applies.

```csharp
// 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");
```

```vbnet
'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")
```

In XML (below the `OpcApplicationConfiguration` element):

```xml
  <ApplicationName>MyClient Configured via XML</ApplicationName>
  <ApplicationUri>http://myclient/application</ApplicationUri>
```

**Configure the session parameters** (in code): Without a `SessionName`, the session gets the name of the application (`ApplicationName`).

```csharp
client.SessionTimeout = 30000;          // Default: 60000
client.SessionName = "My Session Name"; // Default: Value of ApplicationName
```

```vbnet
client.SessionTimeout = 30000           'Default: 60000
client.SessionName = "My Session Name"  'Default: Value of ApplicationName
```

In XML (below the `OpcApplicationConfiguration` element). The client uses the value from the XML file only if its `SessionTimeout` property is set to `0`:

```xml
    <DefaultSessionTimeout>600000</DefaultSessionTimeout>
```

**Configure the connection parameters** (in code): The `OperationTimeout` property sets the maximum time the client waits for the response to a request (120000 milliseconds by default).

```csharp
client.OperationTimeout = 10000;        // Default: 120000
client.DisconnectTimeout = 5000;        // Default: 10000
client.ReconnectInterval = 5000;        // Default: 10000
```

```vbnet
client.OperationTimeout = 10000         'Default: 120000
client.DisconnectTimeout = 5000         'Default: 10000
client.ReconnectInterval = 5000         'Default: 10000
```

In XML (below the `OpcApplicationConfiguration` element):

```xml
    <OperationTimeout>120000</OperationTimeout>
```

**Configure the certificate stores** (in code): By default, the certificate stores are in the `CertificateStores` folder in the application directory. If this directory is not writable, the client uses the `OPC Foundation\CertificateStores` folder below `%ProgramData%` or `%AppData%`. The `OpcCertificateStores.PathProbings` property sets the order in which the client checks these paths.

```csharp
// 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";
```

```vbnet
'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"
```

In XML (below the `OpcApplicationConfiguration` element):

```xml
<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>
```

**Set the preferred languages of the session**: With `Locales`, the client tells the server in which languages it prefers to receive texts such as DisplayName, Description, and event messages. The client passes the languages when it creates the session. If you set none, the server returns its default language.

```csharp
client.Locales.Add("de-DE");
client.Locales.Add("en-US");
 
client.Connect();
 
OpcValue displayName = client.ReadNode("ns=2;s=Machine", OpcAttribute.DisplayName);
```

```vbnet
client.Locales.Add("de-DE")
client.Locales.Add("en-US")

client.Connect()

Dim displayName As OpcValue = client.ReadNode("ns=2;s=Machine", OpcAttribute.DisplayName)
```

## Connection monitoring

Types used: `OpcClient`, `OpcClientKeepAlive`

The section [Detect connection breaks](https://www.traeger.de/en/docs/development/opcua/client/introduction#detect-connection-breaks) of the introduction describes how the client detects connection breaks and restores the connection. The following properties define this behavior. If the `ReconnectInterval` property has the value `0`, the client does not restore the connection but raises the `BreakDetected` event. The `MaxReconnectDuration` property limits how long the client tries (`0` by default, unlimited):

```csharp
client.UseBreakDetection = true;    // Default: true
client.KeepAlive.Interval = 2000;   // Default: 5000
client.ReconnectInterval = 5000;    // Default: 10000
client.MaxReconnectDuration = 0;    // Default: 0 (unlimited)
```

```vbnet
client.UseBreakDetection = True     'Default: True
client.KeepAlive.Interval = 2000    'Default: 5000
client.ReconnectInterval = 5000     'Default: 10000
client.MaxReconnectDuration = 0     'Default: 0 (unlimited)
```

**React to connection breaks**: If the client has created a new session after a break, it raises the `Connected` event instead of `Reconnected`.

```csharp
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.");
}
```

```vbnet
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 Sub

```

**Evaluate the result of the KeepAlive requests**:

```csharp
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);
    }
}
```

```vbnet
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 Sub

```

The page [Long-running clients](https://www.traeger.de/en/docs/development/opcua/client/long-running-clients) describes what the client handles by itself after a break and what the application should consider in continuous operation.

## Data transfer limits

Types used: `OpcClient`, `OpcTransport`

The client limits the size of the data it exchanges with the server. If a value exceeds one of these limits, decoding fails, for example with the status `BadEncodingLimitsExceeded`. If you transfer large strings, arrays, or structures, raise the limits through the client's `Transport` property:

```csharp
client.Transport.MaxStringLength = 1048576;      // Default: 65535
client.Transport.MaxByteStringLength = 10485760; // Default: 5242880
client.Transport.MaxArrayLength = 1000000;       // Default: 65535
client.Transport.MaxMessageSize = 20971520;      // Default: 10485760
```

```vbnet
client.Transport.MaxStringLength = 1048576       'Default: 65535
client.Transport.MaxByteStringLength = 10485760  'Default: 5242880
client.Transport.MaxArrayLength = 1000000        'Default: 65535
client.Transport.MaxMessageSize = 20971520       'Default: 10485760
```

The values correspond to the entries below the `TransportQuotas` element of the XML configuration. In addition, the client automatically splits large read and write requests into multiple requests based on the limits reported by the server.

The section [How the SDK splits large requests](https://www.traeger.de/en/docs/development/opcua/client/bulk-access#how-the-sdk-splits-large-requests) describes how this works and how you can influence the splitting.

## Application certificate

Types used: `OpcClient`, `OpcCertificateManager`, `OpcCertificateSettings`, `OpcClientSecurity`, `OpcCertificateStores`, `OpcCertificateStoreInfo`

The client loads certificates of the types `.der` and `.cer` (public part only) as well as `.pfx` and `.p12` (with private key). If the client should use a secure server endpoint, the certificate must have a private key. An endpoint is secure if its `OpcSecurityMode` is `Sign` or `SignAndEncrypt`.

**Load an existing certificate** from any path:

```csharp
var certificate = OpcCertificateManager.LoadCertificate("MyClientCertificate.pfx");

```

```vbnet
Dim certificate = OpcCertificateManager.LoadCertificate("MyClientCertificate.pfx")

```

**Load a password-protected certificate** with its password:

```csharp
var certificate = OpcCertificateManager.LoadCertificate(
        "MyClientCertificate.pfx",
        password: "password");
```

```vbnet
Dim certificate = OpcCertificateManager.LoadCertificate( _
        "MyClientCertificate.pfx", _
        password:="password")
```

**Create a new certificate** in memory. To set properties such as the validity or the domains, use the `OpcCertificateSettings` class (section [Use your own application certificate](https://www.traeger.de/en/docs/development/opcua/client/deployment#use-your-own-application-certificate)):

```csharp
var certificate = OpcCertificateManager.CreateCertificate(client);

```

```vbnet
Dim certificate = OpcCertificateManager.CreateCertificate(client)

```

**Save the certificate** (to any path):

```csharp
OpcCertificateManager.SaveCertificate("MyClientCertificate.pfx", certificate);

```

```vbnet
OpcCertificateManager.SaveCertificate("MyClientCertificate.pfx", certificate)

```

**Set the client certificate**:

```csharp
client.Certificate = certificate;

```

```vbnet
client.Certificate = certificate

```

The certificate must be stored in the certificate store for **application certificates** (`ApplicationStore`):

```csharp
if (!client.CertificateStores.ApplicationStore.Contains(certificate))
    client.CertificateStores.ApplicationStore.Add(certificate);

```

```vbnet
If Not client.CertificateStores.ApplicationStore.Contains(certificate) Then
    client.CertificateStores.ApplicationStore.Add(certificate)
End If
```

If you set **no certificate**, the client looks in the `ApplicationStore` for a certificate whose name matches the `ApplicationName`. Before that, it raises the `CertificateRequested` event, through which the application can provide a certificate itself. If the client finds no certificate, by default it automatically creates and uses a new certificate. Up to version 2.58, this also applies to an invalid certificate. As of version 2.59, the client keeps an existing but invalid certificate and raises the `CertificateRequested` event with the reason (see [Protect your own certificate](https://www.traeger.de/en/docs/development/opcua/security/client#protect-your-own-certificate)). If that fails as well, it uses a temporary certificate in memory. If the client should use only the specified certificate, turn off this feature. To do so, set the `AutoCreateCertificate` property to `false`:

```csharp
client.CertificateStores.AutoCreateCertificate = false;

```

```vbnet
client.CertificateStores.AutoCreateCertificate = False

```

The page [Secure clients](https://www.traeger.de/en/docs/development/opcua/security/client) describes how the client chooses a secure endpoint, validates server certificates, and logs on with a user identity. It also explains how to harden the client for production.

## Configuration through an XML file

If the client should also be configurable through XML, load its configuration from an XML file. The file must have the following standard XML tree:

```xml
<?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">
```

The settings from the previous sections follow below the `OpcApplicationConfiguration` element. You load the file in one of the following ways:

- **By the path to the XML file** with the `LoadClientConfigFile` method. The file can have any name and be in any location.
- **By the name of the configuration** with the `LoadClientConfig` method. The file must then be named `<Name>.Config.xml` (for example `Opc.UaFx.Client.Config.xml`) and be in the working directory of the application.

Both methods return `null` if the file is missing or cannot be read (section [Configure the application and session](https://www.traeger.de/en/docs/development/opcua/client/configuration#configure-the-application-and-session)). The SDK does not support configuration through the `App.config` of the application (`configSections` with a reference to the XML file).
