After giving a brief introduction to the protocol and seeing how to generate a data model of a simple industrial plant, it’s time to create our OPC UA server.


Although there are several OPC UA implementations on .NET platform, the most convenient, in my opinion, is the one proposed by the OPC Foundation itself: the body that has always controlled and developed the protocol.

The goal of the foundation is to maintain this library so that it is always aligned with the standards they themselves have defined.

The UA .NET Standard Stack is developed entirely in C# using the .NET StandardLibrary. This implies that applications based on it can run on different platforms (Windows, Linux and Mac).

It is one of the few, not to say the only, open source implementation released under GPL 2.0 license.

It is therefore possible to contribute to its development and use it freely, with the only restriction that it cannot be used in commercial applications. If you want to develop a commercial application, you must join the foundation by becoming a Corporate Member.

Environment Setup

We start by creating a new Visual Studio project.

Due to the cross platform nature of the OPC UA stack, we are free to choose either a Console App (.NET Framework) or a Console Application based on .NET Core.

Once opened, we load the Nuget package of the OPC Stack by clicking on Tools -> NuGet Package Manager -> Package Manager Console.

In the console that comes up, we run the following command:

Copy to Clipboard

Model Compilation

At this point, we create the Model folder and save inside it the model developed in the last article (ModelDesign.xml).

We continue then with the creation of the Data folder. Here inside we are going to save the configuration file where the parameters of operation of our server are explained.

For the sake of brevity, I only show the most important parts of the files in the article. At this link you can download the complete blueprint of everything we will discuss from here on out.

We save the file inside the Data folder with the name OPCUAServer.Config.xml.

Here some details about the operation of the server will be specified such as:

  • The name and URI of the server;
Copy to Clipboard

Directories where to find security certificates;

Copy to Clipboard
  • The operating parameters.
Copy to Clipboard

Now we just have to compile, as we have already done, the ModelDesign.xml model.

To do this, we reach the folder where we have the UA ModelCompiler executable, open a Windows console and run the following command:

Copy to Clipboard

This will just generate all the files needed by our server in the Data folder of the project.

Some Configurations

Before proceeding to write the actual code, it is useful to make some settings on the 2 files that will be used by the server:

  • OPCUAServer.Config.xml.
  • OPCUAServer.PredefinedNodes.uanodes, which was generated in the Data folder by the command launched earlier.

From Visual Studio’s Solution Explorer, right-click on one of the 2 files and select Properties.

In the menu that opens, select the Copy if newer option related to the Copy to Output Directory item.

We replicate the operation also for the second file.

By doing so, when we compile our server, Visual Studio will copy these 2 files to the output directory.


NodeManager is a fundamental class because in it we’re going to write methods to handle calls to objects exposed by the server.

The core is represented by two methods

  • LoadPredefinedNodes: in which we load the nodes specified in the generated model (lines 4-7):
Copy to Clipboard
  • CreateAddressSpace: in which, after loading the default nodes (line 5), we retrieve the object generated by the UA Model Compiler containing the various elements of our line (lines 12-13) and then hook the Start and Stop methods of the Conveyor 2 callbacks (lines 19-20).
Copy to Clipboard

Let’s see as an example how the OnStart callback is structured that handles the call to the Start method of the Conveyor object:

Copy to Clipboard

When a client sends a call to execute the Conveyor’s Start method, the server will print the string “Conveyor started.” on the console.

Final Test

To verify that everything is working properly, let’s run a test.

First, let’s launch the OPC server by compiling the project and running it.

If everything went well, you should see a window showing the endpoint where the server is running, in my case:

Copy to Clipboard

At this point, it is necessary to download a client to be able to connect and verify the exposed nodes.

A good free software is UaExpert that can be downloaded by registering for free at the site.

Once installed and run, click on Server -> Add.

In the window that opens, enter the endpoint of our server and give a name to the connection:

Let’s click on OK.

On the main window you should now see the structure of the OPC UA server we created.

By interacting with the various elements you can read their value or make calls to the Conveyor’s methods.

One of the strengths of OPC UA is precisely the ability to make remote calls.

If, instead of UAExpert, we used an OPC UA client of a PLC, we could actually launch methods written in C#!

This allows us to extend the potential of classical automation tools such as the PLC.


In this article, we discussed how to create an OPC UA server from an XML template and the OPC Foundation libraries.

You can download the full project at this link.

Then using a client like UAExpert, we took a look at the structure of the server which consists of nodes, values and methods.

In the next article, we’ll go over how to create an OPC UA client again starting with the .NET libraries.