UA Bundle SDK .NET  2.2.1.258
 All Classes Namespaces Functions Variables Enumerations Enumerator Properties Events Groups Pages
Connect – Simple Connect

Description

The following dialog shows a simple example implementation of the Connect service. Press the button “Show Code” to display the corresponding code, and the button “Help” to show this documentation page.

Note
This example demonstrates how to implement the Connect service. For this purpose, a new session with the server is opened. The settings performed using this dialog window do not affect the other Getting Started Examples.

When pressing the button “Simple Connect”, a connection with the server specified at “Endpoint URL” is established, by default to the Unified Automation .NET Demo Server running on localhost.

At first, the client looks for available Endpoints. When a secure connection is chosen, the client connects to the Endpoint with the highest available security, otherwise an insecure connection is established, i.e. the Endpoint with Security Policy “None” is chosen.

Check the box at “Use Asynchronous Pattern” to call BeginConnect instead of Connect.

When choosing security, client and server have to trust each other’s certificate to enable a connection. In this example, a dialog window for trusting the server’s certificate is used. Press the button “Trust” to trust the certificate for this session and check “Save Certificate in TrustList” to accept the certificate permanently.

To move the client’s certificate to the trust list of the Unified Automation .NET Demo Server, choose the tab “Rejected Certificates”, double-click on the client’s certificate in the list and choose “Trust” in the newly opened dialog window.

When the connection to the server is established this is indicated at connection state:

This example shows different solutions for avoiding problems with clients that are not able to resolve DNS names. To establish a connection, the client needs to know the available Endpoints of a server. For this purpose, GetEndpoints is called first. The server then returns a list of available Endpoints, which may contain host names which the client cannot resolve and thus is not able to connect to these Endpoints.

When “UseDnsNameAndPortFromDiscoveryUrl” is checked, this problem is avoided by replacing the Endpoint URL recieved from the server with the URL which was used for GetEndpoints (i.e. the URL specified at “Endpoint URL”).

Another solution is using the UpdateEndpoint EventHandler:

If the Endpoint URL recieved from the server differs from the Discovery URL, the following dialog window is shown.

There are three options:

  • manually changing the Endpoint URL and confirming with “Update”
  • checking the box at “UseDnsNameAndPortFromDiscoveryUrl” and confirming with “Update” to connect to the Discovery URL
  • pressing the button “No Update” for using the Endpoint URL returned from the server
Note
In this example the UpdateEndpoint EventHandler shows a dialog. For that reason the EventHandler must not be enabled if the Connect method is called synchronously.

Sample Code

There are three relevant EventHandlers for this example. The EventHandlers have to by synchronized with the GUI thread.

private void OnServerConnectionStatusUpdate(Session sender, ServerConnectionStatusUpdateEventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new ServerConnectionStatusUpdateEventHandler(OnServerConnectionStatusUpdate), sender, e);
return;
}
LabelConnectionState.Text = e.Status.ToString();
SetEndpointUrl();
}
private void OnSessionValidationError(Session sender, SessionValidationEventArgs e)
{
if (InvokeRequired)
{
Invoke(new SessionValidationEventHandler(OnSessionValidationError), sender, e);
return;
}
SessionValidationErrorDialog dlg = new SessionValidationErrorDialog();
dlg.ShowDialog(sender, e);
}
private void OnUpdateEndpoint(Session sender, UpdateEndpointEventArgs e)
{
if (InvokeRequired)
{
Invoke(new UpdateEndpointEventHandler(OnUpdateEndpoint), sender, e);
return;
}
// only show the dialog if urls do not match
if (!e.DiscoveryUrl.Equals(e.SelectedEndpoint.EndpointUrl))
{
EndpointUpdateDialog dlg = new EndpointUpdateDialog();
dlg.ShowDialog(sender, e);
if (dlg.DialogResult == DialogResult.OK)
{
e.SelectedEndpoint.EndpointUrl = dlg.EndpointUrl;
e.UseDnsNameAndPortFromDiscoveryUrl = dlg.UseDnsNameAndPortFromDiscoveryUrl;
}
}
}

The EventHandlers are added to the Session.

m_session.ConnectionStatusUpdate += OnServerConnectionStatusUpdate;
m_session.SessionValidationError += OnSessionValidationError;
m_session.UpdateEndpoint += OnUpdateEndpoint;

The following code shows how to connect synchronously to a server. In this example, Session.Connect is called from an own thread. This is necessary if the method is called from a GUI thread and the UpdateEndpoint EventHandler or the UntrustedCertificate EventHandler of the ApplicationInstance open dialogs. Otherwise the method can be called in the same thread directly.

private void Connect()
{
try
{
// disconnect any existing session.
if (m_session.ConnectionStatus != ServerConnectionStatus.Disconnected)
{
m_session.Disconnect();
}
// Call the connect method from another thread to avoid threading problems
// Possible problems are
// - The UpdateEndpoint EventHandler opens a dialog
// - The UntrustedCertificate EventHandler of the ApplicationInstance opens a dialog
Thread t = new Thread(new ParameterizedThreadStart(OnConnect));
t.Start(new ConnectData()
{
Session = m_session,
EndpointUrl = EndpointUrl,
Security = SecuritySelection
});
}
catch (Exception e)
{
ExceptionDlg.Show(this.Text, e);
}
}
public delegate void ShowExceptionDelegate(string text, Exception e);
private void ShowException(string text, Exception e)
{
ExceptionDlg.Show(text, e);
}
internal class ConnectData
{
public Session Session;
public string EndpointUrl;
public SecuritySelection Security;
}
private void OnConnect(object state)
{
ConnectData data = state as ConnectData;
try
{
data.Session.Connect(data.EndpointUrl, data.Security);
}
catch (Exception e)
{
if (InvokeRequired)
{
Invoke(new ShowExceptionDelegate(ShowException), this.Text, e);
return;
}
ExceptionDlg.Show(this.Text, e);
}
}

The following code shows how to connect asynchronously to a server.

private void BeginConnect()
{
try
{
// disconnect any existing session.
if (m_session.ConnectionStatus != ServerConnectionStatus.Disconnected)
{
m_session.Disconnect();
}
// start the operation.
m_session.BeginConnect(
EndpointUrl,
null,
m_session.DefaultRequestSettings,
OnConnectCompleted,
m_session);
}
catch (Exception e)
{
ExceptionDlg.Show(this.Text, e);
}
}
private void OnConnectCompleted(IAsyncResult result)
{
// need to make sure the results are processed on the correct thread.
if (InvokeRequired)
{
BeginInvoke(new AsyncCallback(OnConnectCompleted), result);
return;
}
// get the session used to send the request which was passed as the userData in the Begin call.
Session session = (Session)result.AsyncState;
try
{
session.EndConnect(result);
}
catch (Exception e)
{
ExceptionDlg.Show(this.Text, e);
}
}