C# 中,使用OpcUaHelper读写OPC服务器

在这里插入图片描述

nuget包

帮助类:

using Opc.Ua.Client;
using Opc.Ua;
using OpcUaHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace MyOPCUATest
{

    public class OPCUAHelper
    {
        #region   基础参数
        //OPCUA客户端
        private OpcUaClient opcUaClient;


        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public OPCUAHelper()
        {
            opcUaClient = new OpcUaClient();
        }

        /// <summary>
        /// 连接状态
        /// </summary>
        public bool ConnectStatus
        {
            get { return opcUaClient.Connected; }
        }



        #region   公有方法


        /// <summary>
        /// 打开连接【匿名方式】
        /// </summary>
        /// <param name="serverUrl">服务器URL【格式:opc.tcp://服务器IP地址/服务名称】</param>
        public async void OpenConnectOfAnonymous(string serverUrl)
        {

            if (!string.IsNullOrEmpty(serverUrl))
            {
                try
                {
                    opcUaClient.UserIdentity = new UserIdentity(new AnonymousIdentityToken());

                    await opcUaClient.ConnectServer(serverUrl);

                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("连接失败!!!", ex);
                }

            }
        }

        /// <summary>
        /// 打开连接【账号方式】
        /// </summary>
        /// <param name="serverUrl">服务器URL【格式:opc.tcp://服务器IP地址/服务名称】</param>
        /// <param name="userName">用户名称</param>
        /// <param name="userPwd">用户密码</param>
        public async void OpenConnectOfAccount(string serverUrl, string userName, string userPwd)
        {
            if (!string.IsNullOrEmpty(serverUrl) &&
                !string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(userPwd))
            {
                try
                {
                    opcUaClient.UserIdentity = new UserIdentity(userName, userPwd);

                    await opcUaClient.ConnectServer(serverUrl);
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("连接失败!!!", ex);
                }
            }

        }

        /// <summary>
        /// 打开连接【证书方式】
        /// </summary>
        /// <param name="serverUrl">服务器URL【格式:opc.tcp://服务器IP地址/服务名称】</param>
        /// <param name="certificatePath">证书路径</param>
        /// <param name="secreKey">密钥</param>
        public async void OpenConnectOfCertificate(string serverUrl, string certificatePath, string secreKey)
        {
            if (!string.IsNullOrEmpty(serverUrl) &&
                !string.IsNullOrEmpty(certificatePath) && !string.IsNullOrEmpty(secreKey))
            {
                try
                {
                    X509Certificate2 certificate = new X509Certificate2(certificatePath, secreKey, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
                    opcUaClient.UserIdentity = new UserIdentity(certificate);

                    await opcUaClient.ConnectServer(serverUrl);
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("连接失败!!!", ex);
                }
            }
        }


        /// <summary>
        /// 关闭连接
        /// </summary>
        public void CloseConnect()
        {
            if (opcUaClient != null)
            {
                try
                {
                    opcUaClient.Disconnect();
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("关闭连接失败!!!", ex);
                }

            }
        }


        /// <summary>
        /// 获取到当前节点的值【同步读取】
        /// </summary>
        /// <typeparam name="T">节点对应的数据类型</typeparam>
        /// <param name="nodeId">节点</param>
        /// <returns>返回当前节点的值</returns>
        public T GetCurrentNodeValue<T>(string nodeId)
        {
            T value = default(T);
            if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
            {
                try
                {
                    value = opcUaClient.ReadNode<T>(nodeId);
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("读取失败!!!", ex);
                }
            }

            return value;
        }

        /// <summary>
        /// 获取到当前节点数据【同步读取】
        /// </summary>
        /// <typeparam name="T">节点对应的数据类型</typeparam>
        /// <param name="nodeId">节点</param>
        /// <returns>返回当前节点的值</returns>
        public DataValue GetCurrentNodeValue(string nodeId)
        {
            DataValue dataValue = null;
            if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
            {
                try
                {
                    dataValue = opcUaClient.ReadNode(nodeId);
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("读取失败!!!", ex);
                }
            }

            return dataValue;
        }

        /// <summary>
        /// 获取到批量节点数据【同步读取】
        /// </summary>
        /// <param name="nodeIds">节点列表</param>
        /// <returns>返回节点数据字典</returns>
        public Dictionary<string, DataValue> GetBatchNodeDatasOfSync(List<NodeId> nodeIdList)
        {
            Dictionary<string, DataValue> dicNodeInfo = new Dictionary<string, DataValue>();
            if (nodeIdList != null && nodeIdList.Count > 0 && ConnectStatus)
            {
                try
                {
                    List<DataValue> dataValues = opcUaClient.ReadNodes(nodeIdList.ToArray());

                    int count = nodeIdList.Count;
                    for (int i = 0; i < count; i++)
                    {
                        AddInfoToDic(dicNodeInfo, nodeIdList[i].ToString(), dataValues[i]);
                    }
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("读取失败!!!", ex);
                }
            }

            return dicNodeInfo;
        }


        /// <summary>
        /// 获取到当前节点的值【异步读取】
        /// </summary>
        /// <typeparam name="T">节点对应的数据类型</typeparam>
        /// <param name="nodeId">节点</param>
        /// <returns>返回当前节点的值</returns>
        public async Task<T> GetCurrentNodeValueOfAsync<T>(string nodeId)
        {
            T value = default(T);
            if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
            {
                try
                {
                    value = await opcUaClient.ReadNodeAsync<T>(nodeId);
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("读取失败!!!", ex);
                }
            }

            return value;
        }

        /// <summary>
        /// 获取到批量节点数据【异步读取】
        /// </summary>
        /// <param name="nodeIds">节点列表</param>
        /// <returns>返回节点数据字典</returns>
        public async Task<Dictionary<string, DataValue>> GetBatchNodeDatasOfAsync(List<NodeId> nodeIdList)
        {
            Dictionary<string, DataValue> dicNodeInfo = new Dictionary<string, DataValue>();
            if (nodeIdList != null && nodeIdList.Count > 0 && ConnectStatus)
            {
                try
                {
                    List<DataValue> dataValues = await opcUaClient.ReadNodesAsync(nodeIdList.ToArray());

                    int count = nodeIdList.Count;
                    for (int i = 0; i < count; i++)
                    {
                        AddInfoToDic(dicNodeInfo, nodeIdList[i].ToString(), dataValues[i]);
                    }
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("读取失败!!!", ex);
                }
            }

            return dicNodeInfo;
        }




        /// <summary>
        /// 获取到当前节点的关联节点
        /// </summary>
        /// <param name="nodeId">当前节点</param>
        /// <returns>返回当前节点的关联节点</returns>
        public ReferenceDescription[] GetAllRelationNodeOfNodeId(string nodeId)
        {
            ReferenceDescription[] referenceDescriptions = null;

            if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
            {
                try
                {
                    referenceDescriptions = opcUaClient.BrowseNodeReference(nodeId);
                }
                catch (Exception ex)
                {
                    string str = "获取当前: " + nodeId + "  节点的相关节点失败!!!";
                    ClientUtils.HandleException(str, ex);
                }
            }

            return referenceDescriptions;
        }


        /// <summary>
        /// 获取到当前节点的所有属性
        /// </summary>
        /// <param name="nodeId">当前节点</param>
        /// <returns>返回当前节点对应的所有属性</returns>
        public OpcNodeAttribute[] GetCurrentNodeAttributes(string nodeId)
        {
            OpcNodeAttribute[] opcNodeAttributes = null;
            if (!string.IsNullOrEmpty(nodeId) && ConnectStatus)
            {
                try
                {
                    opcNodeAttributes = opcUaClient.ReadNoteAttributes(nodeId);
                }
                catch (Exception ex)
                {
                    string str = "读取节点;" + nodeId + "  的所有属性失败!!!";
                    ClientUtils.HandleException(str, ex);
                }
            }

            return opcNodeAttributes;
        }

        /// <summary>
        /// 写入单个节点【同步方式】
        /// </summary>
        /// <typeparam name="T">写入节点值得数据类型</typeparam>
        /// <param name="nodeId">节点</param>
        /// <param name="value">节点对应的数据值(比如:(short)123))</param>
        /// <returns>返回写入结果(true:表示写入成功)</returns>
        public bool WriteSingleNodeId<T>(string nodeId, T value)
        {
            bool success = false;

            if (opcUaClient != null && ConnectStatus)
            {
                if (!string.IsNullOrEmpty(nodeId))
                {
                    try
                    {
                        success = opcUaClient.WriteNode(nodeId, value);
                    }
                    catch (Exception ex)
                    {
                        string str = "当前节点:" + nodeId + "  写入失败";
                        ClientUtils.HandleException(str, ex);
                    }
                }

            }

            return success;
        }

        /// <summary>
        /// 批量写入节点
        /// </summary>
        /// <param name="nodeIdArray">节点数组</param>
        /// <param name="nodeIdValueArray">节点对应数据数组</param>
        /// <returns>返回写入结果(true:表示写入成功)</returns>
        public bool BatchWriteNodeIds(string[] nodeIdArray, object[] nodeIdValueArray)
        {
            bool success = false;
            if (nodeIdArray != null && nodeIdArray.Length > 0 &&
                nodeIdValueArray != null && nodeIdValueArray.Length > 0)

            {
                try
                {
                    success = opcUaClient.WriteNodes(nodeIdArray, nodeIdValueArray);
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("批量写入节点失败!!!", ex);
                }
            }
            return success;
        }

        /// <summary>
        /// 写入单个节点【异步方式】
        /// </summary>
        /// <typeparam name="T">写入节点值得数据类型</typeparam>
        /// <param name="nodeId">节点</param>
        /// <param name="value">节点对应的数据值</param>
        /// <returns>返回写入结果(true:表示写入成功)</returns>
        public async Task<bool> WriteSingleNodeIdOfAsync<T>(string nodeId, T value)
        {
            bool success = false;

            if (opcUaClient != null && ConnectStatus)
            {
                if (!string.IsNullOrEmpty(nodeId))
                {
                    try
                    {
                        success = await opcUaClient.WriteNodeAsync(nodeId, value);
                    }
                    catch (Exception ex)
                    {
                        string str = "当前节点:" + nodeId + "  写入失败";
                        ClientUtils.HandleException(str, ex);
                    }
                }

            }

            return success;
        }


        /// <summary>
        /// 读取单个节点的历史数据记录
        /// </summary>
        /// <typeparam name="T">节点的数据类型</typeparam>
        /// <param name="nodeId">节点</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>返回该节点对应的历史数据记录</returns>
        public List<T> ReadSingleNodeIdHistoryDatas<T>(string nodeId, DateTime startTime, DateTime endTime)
        {
            List<T> nodeIdDatas = null;
            if (!string.IsNullOrEmpty(nodeId) && startTime != null && endTime != null && endTime > startTime)
            {
                try
                {
                    nodeIdDatas = opcUaClient.ReadHistoryRawDataValues<T>(nodeId, startTime, endTime).ToList();
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("读取失败", ex);
                }
            }

            return nodeIdDatas;
        }

        /// <summary>
        /// 读取单个节点的历史数据记录
        /// </summary>
        /// <typeparam name="T">节点的数据类型</typeparam>
        /// <param name="nodeId">节点</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns>返回该节点对应的历史数据记录</returns>
        public List<DataValue> ReadSingleNodeIdHistoryDatas(string nodeId, DateTime startTime, DateTime endTime)
        {
            List<DataValue> nodeIdDatas = null;
            if (!string.IsNullOrEmpty(nodeId) && startTime != null && endTime != null && endTime > startTime)
            {
                if (ConnectStatus)
                {
                    try
                    {
                        nodeIdDatas = opcUaClient.ReadHistoryRawDataValues(nodeId, startTime, endTime).ToList();
                    }
                    catch (Exception ex)
                    {
                        ClientUtils.HandleException("读取失败", ex);
                    }
                }

            }

            return nodeIdDatas;
        }


        /// <summary>
        /// 单节点数据订阅
        /// </summary>
        /// <param name="key">订阅的关键字(必须唯一)</param>
        /// <param name="nodeId">节点</param>
        /// <param name="callback">数据订阅的回调方法</param>
        public void SingleNodeIdDatasSubscription(string key, string nodeId, Action<string, MonitoredItem, MonitoredItemNotificationEventArgs> callback)
        {
            if (ConnectStatus)
            {
                try
                {
                    opcUaClient.AddSubscription(key, nodeId, callback);
                }
                catch (Exception ex)
                {
                    string str = "订阅节点:" + nodeId + " 数据失败!!!";
                    ClientUtils.HandleException(str, ex);
                }
            }
        }

        /// <summary>
        /// 取消单节点数据订阅
        /// </summary>
        /// <param name="key">订阅的关键字</param>
        public bool CancelSingleNodeIdDatasSubscription(string key)
        {
            bool success = false;
            if (!string.IsNullOrEmpty(key))
            {
                if (ConnectStatus)
                {
                    try
                    {
                        opcUaClient.RemoveSubscription(key);
                        success = true;
                    }
                    catch (Exception ex)
                    {
                        string str = "取消 " + key + " 的订阅失败";
                        ClientUtils.HandleException(str, ex);
                    }

                }
            }

            return success;
        }


        /// <summary>
        /// 批量节点数据订阅
        /// </summary>
        /// <param name="key">订阅的关键字(必须唯一)</param>
        /// <param name="nodeIds">节点数组</param>
        /// <param name="callback">数据订阅的回调方法</param>
        public void BatchNodeIdDatasSubscription(string key, string[] nodeIds, Action<string, MonitoredItem, MonitoredItemNotificationEventArgs> callback)
        {
            if (!string.IsNullOrEmpty(key) && nodeIds != null && nodeIds.Length > 0)
            {
                if (ConnectStatus)
                {
                    try
                    {
                        opcUaClient.AddSubscription(key, nodeIds, callback);
                    }
                    catch (Exception ex)
                    {
                        string str = "批量订阅节点数据失败!!!";
                        ClientUtils.HandleException(str, ex);
                    }
                }
            }

        }

        /// <summary>
        /// 取消所有节点的数据订阅
        /// </summary>
        /// <returns></returns>
        public bool CancelAllNodeIdDatasSubscription()
        {
            bool success = false;

            if (ConnectStatus)
            {
                try
                {
                    opcUaClient.RemoveAllSubscription();
                    success = true;
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("取消所有的节点数据订阅失败!!!", ex);
                }

            }

            return success;
        }


        /// <summary>
        /// 取消单节点的数据订阅
        /// </summary>
        /// <returns></returns>
        public bool CancelNodeIdDatasSubscription(string key)
        {
            bool success = false;

            if (ConnectStatus)
            {
                try
                {
                    opcUaClient.RemoveSubscription(key);
                    success = true;
                }
                catch (Exception ex)
                {
                    ClientUtils.HandleException("取消节点数据订阅失败!!!", ex);
                }

            }

            return success;
        }

        #endregion



        #region   私有方法

        /// <summary>
        /// 添加数据到字典中(相同键的则采用最后一个键对应的值)
        /// </summary>
        /// <param name="dic">字典</param>
        /// <param name="key">键</param>
        /// <param name="dataValue">值</param>
        private void AddInfoToDic(Dictionary<string, DataValue> dic, string key, DataValue dataValue)
        {
            if (dic != null)
            {
                if (!dic.ContainsKey(key))
                {

                    dic.Add(key, dataValue);
                }
                else
                {
                    dic[key] = dataValue;
                }
            }

        }




        #endregion

    }//Class_end

}

Winform:

using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyOPCUATest
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }
        private OPCUAHelper opcClient;

        private string[] MonitorNodeTags = null;
        Dictionary<string, object> myDic = new Dictionary<string, object>();

        private void BtnConn_Click(object sender, EventArgs e)
        {
            string url = "opc.tcp://192.168.2.11:4840";
            string userName = "Administrator";
            string password = "123456";
            opcClient = new OPCUAHelper();
            //opcClient.OpenConnectOfAccount(url, userName, password);
            opcClient.OpenConnectOfAnonymous(url);
            MessageBox.Show(opcClient.ConnectStatus.ToString());
        }

        private void BtnCurrentNode_Click(object sender, EventArgs e)
        {
            //string nodeId = "\"S7MesData\".\"S7Real\"[0]";
            string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]";
            DataValue myValue= opcClient.GetCurrentNodeValue(nodeId);
            this.Txtbox.Text = myValue.ToString();
        }

        private void BtnCertificate_Click(object sender, EventArgs e)
        {
            string url = "opc.tcp://192.168.2.11:4840";
            string path = "D:\\zhengshu\\security\\zg-client.pfx";
            string key = "123456";
            opcClient = new OPCUAHelper();
            opcClient.OpenConnectOfCertificate(url, path, key);
            MessageBox.Show(opcClient.ConnectStatus.ToString());

        }

        private void BtnSigleScribe_Click(object sender, EventArgs e)
        {
            List<string> list = new List<string>();
            list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[0]");
            list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[1]");
            MonitorNodeTags = list.ToArray();

            opcClient.BatchNodeIdDatasSubscription("B", MonitorNodeTags, SubCallback);
        }

        private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
        {
            if (key == "B")
            {
                MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;

                
                if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[0])
                {
                    textBox2.Invoke(new Action(() =>
                    {
                        textBox2.Text = notification.Value.WrappedValue.Value.ToString();
                    }));

                }
                else if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[1])
                {
                    textBox3.Invoke(new Action(() =>
                    {
                        textBox3.Text = notification.Value.WrappedValue.Value.ToString();
                    }));

                }

                if (myDic.ContainsKey(monitoredItem.StartNodeId.ToString()))
                {
                    myDic[monitoredItem.StartNodeId.ToString()] = notification.Value.WrappedValue.Value;
                }
                else
                {
                    myDic.Add(monitoredItem.StartNodeId.ToString(), notification.Value.WrappedValue.Value);
                }
                string str = "";
                //foreach (var item in myDic)
                //{
                //    Console.WriteLine(item.Key);
                //    Console.WriteLine(item.Value);
                //}
            }
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            string myTxt = textBox4.Text.Trim();
            string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]";
            opcClient.WriteSingleNodeId(nodeId, (float)Convert.ToDouble(myTxt));
           
        }
    }
}

KepServer 设置:

using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace MyOPCUATest
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }
        private OPCUAHelper opcClient;

        private string[] MonitorNodeTags = null;
        Dictionary<string, object> myDic = new Dictionary<string, object>();

        private void BtnConn_Click(object sender, EventArgs e)
        {
            //string url = "opc.tcp://192.168.2.11:4840";  //PLC
            string url = "opc.tcp://192.168.2.125:49320"; //KepServer
            string userName = "Administrator";
            string password = "123456";
            opcClient = new OPCUAHelper();
            opcClient.OpenConnectOfAccount(url, userName, password);
            //opcClient.OpenConnectOfAnonymous(url);
            MessageBox.Show(opcClient.ConnectStatus.ToString());
        }

        private void BtnCurrentNode_Click(object sender, EventArgs e)
        {
            //string nodeId = "\"S7MesData\".\"S7Real\"[0]";
            //string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]"; //PLC

            string nodeId = "ns=2;s=KxOPC.KX1500.电压1"; //Kep

            DataValue myValue = opcClient.GetCurrentNodeValue(nodeId);
            this.Txtbox.Text = myValue.ToString();
        }

        private void BtnCertificate_Click(object sender, EventArgs e)
        {
            //string url = "opc.tcp://192.168.2.11:4840";
            string url = "opc.tcp://192.168.2.125:49320"; //KepServer
            string path = @"D:\zhengshu\security\zg-client.pfx";
            string key = "123456";
            opcClient = new OPCUAHelper();
            opcClient.OpenConnectOfCertificate(url, path, key);
            MessageBox.Show(opcClient.ConnectStatus.ToString());

        }

        private void BtnSigleScribe_Click(object sender, EventArgs e)
        {
            List<string> list = new List<string>();
            list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[0]");
            list.Add("ns=3;s=\"S7MesData\".\"S7Real\"[1]");
            MonitorNodeTags = list.ToArray();

            opcClient.BatchNodeIdDatasSubscription("B", MonitorNodeTags, SubCallback);
        }

        private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args)
        {
            if (key == "B")
            {
                MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;


                if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[0])
                {
                    textBox2.Invoke(new Action(() =>
                    {
                        textBox2.Text = notification.Value.WrappedValue.Value.ToString();
                    }));

                }
                else if (monitoredItem.StartNodeId.ToString() == MonitorNodeTags[1])
                {
                    textBox3.Invoke(new Action(() =>
                    {
                        textBox3.Text = notification.Value.WrappedValue.Value.ToString();
                    }));

                }

                if (myDic.ContainsKey(monitoredItem.StartNodeId.ToString()))
                {
                    myDic[monitoredItem.StartNodeId.ToString()] = notification.Value.WrappedValue.Value;
                }
                else
                {
                    myDic.Add(monitoredItem.StartNodeId.ToString(), notification.Value.WrappedValue.Value);
                }
                string str = "";
                //foreach (var item in myDic)
                //{
                //    Console.WriteLine(item.Key);
                //    Console.WriteLine(item.Value);
                //}
            }
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            string myTxt = textBox4.Text.Trim();
            string nodeId = "ns=3;s=\"S7MesData\".\"S7Real\"[0]";
            opcClient.WriteSingleNodeId(nodeId, (float)Convert.ToDouble(myTxt));

        }
    }
}

结果:

在这里插入图片描述

在这里插入图片描述

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用C#编写一个OPCUA服务器时,你可以使用OPCUA库来简化开发过程。以下是一个简单的示例: 首先,你需要在项目引用OPCUA库。你可以通过NuGet包管理器搜索并安装OPCUA库。 接下来,在你的代码添加必要的命名空间引用: ```csharp using Opc.Ua; using Opc.Ua.Server; ``` 然后,创建一个类来实现OPCUA服务器: ```csharp public class OpcuaServer : StandardServer { public OpcuaServer() { // 设置服务器的名称 this.ServerName = "MyOPCUAServer"; // 添加你的自定义节点管理器 this.AddNodeManager(new YourNodeManager()); } protected override void Dispose(bool disposing) { // 在释放服务器之前执行清理操作 base.Dispose(disposing); } } public class YourNodeManager : CustomNodeManager2 { public YourNodeManager() : base(new YourNamespaceTable()) { // 添加你的自定义节点 // AddNode方法用于添加节点到OPCUA服务器 // 在这里添加你的节点 // 示例代码: // 添加一个Object节点 var objectNode = new MyObjectNode(); this.AddNode(objectNode); // 添加一个Variable节点 var variableNode = new MyVariableNode(); variableNode.Value = new Variant(0); this.AddNode(variableNode); } } public class MyObjectNode : BaseObjectState { public MyObjectNode() { // 设置节点的属性 this.DisplayName = "MyObject"; } } public class MyVariableNode : BaseDataVariableState { public MyVariableNode() { // 设置节点的属性 this.DisplayName = "MyVariable"; this.TypeDefinitionId = VariableTypeIds.Int32; } } ``` 最后,在你的应用程序的入口点创建并启动OPCUA服务器: ```csharp class Program { static void Main(string[] args) { // 创建OPCUA服务器实例 var server = new OpcuaServer(); // 启动服务器 server.Start(); Console.WriteLine("OPCUA server started. Press Enter to exit."); Console.ReadLine(); // 停止服务器 server.Stop(); } } ``` 这是一个基本的OPCUA服务器示例,你可以根据你的需求进行扩展和修改。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值