C# OPC UA 服务器端源码 该源码未使用任何第三方支持库,纯代码实现

一、项目基础信息与工程结构

(一)工程核心配置

该OPC UA服务器端项目基于C#语言开发,工程文件(IcsRadeTech.API.csproj)定义了核心编译与依赖规则,关键配置如下:

  • 框架版本:目标框架为.NET Framework 4.6.1,兼容Windows主流操作系统,支持通过Mono实现跨平台运行。
  • 编译模式:区分Debug与Release模式,Debug模式启用AllowUnsafeBlocks(支持不安全代码)、生成XML文档(IcsRadeTech.API.xml),便于调试与接口文档查阅;Release模式启用代码优化,减少运行时资源占用。
  • 签名配置:包含IcsRadeTech® API For Personal.pfx证书文件,默认关闭强签名(SignAssembly=false),可根据部署需求开启。
  • 依赖引用:除系统基础库(如SystemSystem.CoreSystem.Net.Http)外,还引入Newtonsoft.Json(用于JSON数据处理)、System.Buffers/System.Memory(内存优化)等,所有第三方库通过本地路径或NuGet包管理,确保部署独立性。

(二)代码文件组织

项目核心代码集中在IcsRadeTech.API.OpcServer命名空间下,按功能划分为多个子模块,共111个文件,关键文件与职责如下表:

核心文件/目录 所在路径 核心职责
AddressSpace.cs OpcServer/ 定义地址空间节点模型、节点关系管理、地址空间初始化
Application.cs OpcServer/ 服务器会话管理、请求处理(读/写/浏览)、监控项与事件通知逻辑
Security.csCryptography子目录 OpcServer/ 实现AES/RSA加密、X509证书管理、HMAC哈希验证等安全机制
Encoding.cs OpcServer/ OPC UA协议数据编码/解码(二进制/XML)、数据类型序列化
NetDispatcher.cs OpcServer/ 网络数据分发、异步通信处理、客户端连接管理
DemoLogger.cs/ILogger.cs OpcServer/ 日志接口定义与默认实现,支持服务器运行状态、错误信息记录
Server.cs/ServerConfig.cs OpcServer/ 服务器启动配置、核心服务初始化、客户端请求分发入口

二、核心功能模块深度解析

(一)地址空间模块:OPC UA数据模型的核心实现

地址空间是OPC UA服务器的“数据字典”,AddressSpace.cs通过面向对象设计,完整实现了OPC UA规范定义的节点模型与关系管理,是客户端访问数据的基础。

1. 节点模型核心设计

代码定义了9种核心节点类型,所有节点均继承自Node基类,通过多态实现属性与行为的差异化,完全覆盖OPC UA标准节点分类:

  • Node基类:封装所有节点的通用属性,包括NodeId(节点唯一标识)、BrowseName(浏览名)、DisplayName(显示名)、WriteMask(写权限掩码)、UserWriteMask(用户写权限掩码)及References(节点间引用列表),并提供GetNodeClass()方法用于判断节点具体类型。
  • NodeId:实现节点唯一标识,支持三种标识类型(通过NodeIdNetType枚举区分):
  • 数值型(Numeric):如ns=0;i=2253(命名空间0下的数值节点2253);
  • 字符串型(String):如ns=1;s=Temperature(命名空间1下的字符串节点“Temperature”);
  • 字节串/ Guid型(ByteString/Guid):通过字节数组存储标识。
    同时提供TryParse()方法,支持解析客户端传入的节点标识字符串,例如将“ns=0;i=123”解析为对应的NodeId对象。
  • 具体节点类型
  • NodeObject:表示设备、系统组件等实体对象,包含EventNotifier属性(事件通知能力标识);
  • NodeVariable:存储可读写数据,核心属性包括Value(节点值)、DataType(数据类型NodeId)、AccessLevel(访问权限)、MinimumResamplingInterval(最小采样间隔);
  • NodeMethod:定义可执行方法,通过IsExecutable/IsUserExecutable控制执行权限;
  • 其他类型(NodeObjectType/NodeVariableType/NodeReferenceType等):用于定义节点模板、数据结构规则,例如NodeReferenceType定义节点间引用的类型(如OrganizesHasTypeDefinition)。
2. 地址空间初始化逻辑

代码通过SetupDefaultAddressSpace()方法初始化OPC UA标准地址空间,构建“Root-Objects-Types-Views”四级根节点结构,并预设核心节点与引用关系:

  • 根节点(Root,i=84):作为地址空间顶层节点,通过Organizes引用关联Objects(i=85)、Types(i=86)、Views(i=87)节点;
  • Objects节点(i=85):存储服务器实例对象,默认包含Server节点(i=2253),用于暴露服务器状态与能力;
  • Types节点(i=86):存储节点类型模板,包含ObjectTypes(i=88)、VariableTypes(i=89)、DataTypes(i=90)等子节点,例如ObjectTypes下的BaseObjectType(i=58)是所有对象节点的基类型;
  • 预设引用关系:通过ReferenceNode类定义节点间关联,例如Server节点(i=2253)通过HasComponent引用关联ServerStatus(i=2256)、ServerCapabilities(i=2268)等子节点,确保客户端可通过标准路径浏览服务器资源。
3. 内部地址空间维护

代码通过SetupInternalAddressSpace()方法初始化内部地址空间数据,预设服务器运行所需的核心配置与状态变量,例如:

  • 命名空间数组(Server_NamespaceArray):默认包含3个命名空间(http://opcfoundation.org/UA/http://quantensystems.com/uaSDK2http://quantensystems.com/DemoServer);
  • 服务器状态(ServerServerStatusState):默认设为Running(运行状态);
  • 操作限制(OperationLimitsType_MaxNodesPerRead):默认限制单次读请求最大节点数为100。

(二)服务器核心逻辑模块:会话与请求处理

Application.cs是服务器的“大脑”,封装了会话管理、客户端请求处理、监控项与事件通知等核心逻辑,完全遵循OPC UA交互协议。

1. 会话生命周期管理

代码通过结构化设计实现会话的创建、验证、激活与释放,支持多客户端并发访问:

  • 会话创建(SessionCreate:接收客户端连接端点(SessionCreationInfo.Endpoint),返回会话对象(默认返回null,可扩展实现会话状态存储);
  • 客户端验证
  • SessionValidateClientApplication:验证客户端应用描述(ApplicationDescription)与客户端证书(clientCertificate),默认返回true,可扩展实现证书链验证;
  • SessionValidateClientUser:验证客户端身份令牌(userIdentityToken),支持匿名令牌、用户名密码令牌、X509证书令牌等类型;
  • 会话激活(SessionActivateClient:协商安全策略(SecurityPolicy)与消息安全模式(MessageSecurityMode),验证客户端证书(remoteCertificate),确保通信安全;
  • 会话释放(SessionRelease:释放会话资源,默认空实现,可扩展实现会话超时清理、资源回收。
2. 核心请求处理实现

代码实现了OPC UA标准的五大核心请求接口,覆盖客户端90%以上的交互场景,处理逻辑如下:

  • 读请求(HandleReadRequest
    1. 遍历客户端传入的ReadValueId数组,逐个检查节点是否存在(通过AddressSpaceTable.TryGetValue)与访问权限(SessionHasPermissionToRead);
    2. 根据AttributeId(属性ID)返回对应属性值,例如:
  • NodeAttribute.Value:调用HandleReadRequestInternal读取节点值,优先从内部地址空间(internalAddressSpaceValues)获取;
  • NodeAttribute.NodeClass:通过node.GetNodeClass()返回节点类型(如NodeClass.ObjectNodeClass.Variable);
  • 其他属性(BrowseName/DisplayName/WriteMask等):直接读取节点对应属性;
    3. 若节点不存在或无权限,返回StatusCode.BadNodeIdUnknown;若属性不支持,返回StatusCode.BadAttributeIdInvalid
  • 写请求(HandleWriteRequest
    1. 接收客户端传入的WriteValue数组,默认返回全Good状态码(StatusCode.Good);
    2. 可扩展实现:增加节点写权限检查(AccessLevel)、数据类型验证、实际值写入逻辑(如写入设备寄存器、数据库)。
  • 浏览请求(HandleBrowseRequest
    1. 验证目标节点是否存在与访问权限,遍历节点的References列表;
    2. 根据BrowseDirection(浏览方向)、ReferenceType(引用类型)、NodeClassMask(节点类型掩码)筛选符合条件的引用;
    3. 支持分页浏览:当结果数量超过maxResults时,通过ContinuationPointBrowse记录偏移量,返回StatusCode.GoodMoreData
    4. 构建ReferenceDescription列表,包含引用类型、目标节点ID、目标节点浏览名等信息,返回给客户端。
  • 地址空间查询(HandleTranslateBrowsePathRequest
    1. 从BrowsePath.StartingNode(起始节点)开始,逐个解析RelativePath(相对路径);
    2. 根据RelativePathReferenceTypeId(引用类型ID)、TargetName(目标名)匹配子节点,若匹配失败,返回StatusCode.BadNoMatch
    3. 成功匹配后,返回目标节点ID与剩余路径索引(RemainingPathIndex)。
  • 历史数据请求
  • HandleHistoryReadRequest/HandleHistoryUpdateRequest/HandleHistoryEventReadRequest:默认返回StatusCode.BadNotImplemented,可扩展集成时序数据库(如InfluxDB、TimescaleDB)实现历史数据读写。
3. 监控项与事件通知

代码通过“监控项-订阅”模型实现数据变化与事件通知,核心逻辑如下:

  • 监控项管理
  • MonitorAdd:检查节点存在性与访问权限后,将MonitoredItem加入monitorMap(键为ServerMonitorKey,由NodeIdAttributeId组成);
  • MonitorRemove:从monitorMap中移除指定MonitoredItem,释放监控资源;
  • 数据变化通知(MonitorNotifyDataChange
    1. 当节点值变化时,构建DataValue对象(包含新值与状态码);
    2. 根据NodeIdNodeAttribute.Value构建ServerMonitorKey,从monitorMap获取关联的MonitoredItem列表;
    3. 将DataValue加入MonitoredItem.QueueData队列,若队列溢出(超过QueueSize),设置QueueOverflowed=true
    4. 标记订阅的ChangeNotificationAtPublish,客户端通过Publish请求获取变化数据;
  • 事件通知(MonitorNotifyEvent:逻辑与数据变化通知类似,将EventNotification加入MonitoredItem.QueueEvent队列,支持设备故障、系统状态变化等事件的分发。

(三)安全模块:加密与证书管理

安全是OPC UA的核心特性,代码通过Security.csCryptography子目录实现完整的安全机制,覆盖数据加密、签名验证、证书管理等场景。

1. 加密算法实现

代码基于Windows Crypto API(CNG)实现多种加密算法,避免第三方库依赖,核心实现如下:

  • 对称加密
  • AesCng:封装AES加密算法,支持BCrypt底层API,提供加密/解密方法;
  • TripleDESCng:实现三重DES加密,兼容旧版OPC UA客户端;
  • 非对称加密
  • RSACng:基于CNG实现RSA算法,支持密钥生成、签名、加密操作,用于客户端身份验证与密钥交换;
  • 哈希与HMAC
  • HMACSHA256Cng/HMACSHA384Cng/HMACSHA512Cng:基于CNG的HMAC哈希算法,用于数据完整性校验;
  • BCryptHMAC:封装BCrypt HMAC API,支持自定义哈希算法;
  • 密钥派生
  • BCryptPBKDF2:实现PBKDF2密钥派生算法,用于从密码生成加密密钥。
2. X509证书管理

代码通过Security.Cryptography.X509Certificates子目录实现证书的加载、验证与扩展,核心类如下:

  • X509Certificate2ExtensionMethods:提供证书扩展方法,如获取证书备用名称、验证证书链;
  • X509CertificateCreationParameters:定义证书创建参数,如密钥算法、有效期、扩展字段;
  • SafeCertContextHandle:封装证书上下文句柄,确保资源安全释放;
  • X509AlternateName系列类:支持证书备用名称(IP地址、字符串、GUID等),用于服务器多端点配置。
3. 安全策略支持

代码通过SecurityPolicy枚举与MessageSecurityMode枚举支持OPC UA标准安全策略,例如:

  • 安全策略:None(无安全)、Basic128Rsa15(AES-128加密+RSA-SHA1签名)、Basic256(AES-256加密+RSA-SHA1签名)、Basic256Sha256(AES-256加密+RSA-SHA256签名);
  • 消息安全模式:None(无安全)、Sign(仅签名)、SignAndEncrypt(签名+加密);
  • 会话激活时,通过SessionActivateClient协商安全策略与模式,确保通信安全。

(四)辅助模块:编码、日志与网络

1. 数据编码(`Encoding.cs`)

实现OPC UA标准的二进制与XML编码,支持数据类型的序列化与反序列化,核心功能包括:

  • 基础类型编码:如BooleanInt32StringDateTime等类型的二进制打包;
  • 复杂类型编码:如NodeIdQualifiedNameLocalizedTextDataValue等OPC UA特有类型的编码;
  • 可扩展实现:增加自定义数据类型(如设备特定数据结构)的编码逻辑。
2. 日志模块(`DemoLogger.cs`/`ILogger.cs`)
  • ILogger接口:定义日志记录方法(如Info/Warn/Error);
  • DemoLogger:默认日志实现,可扩展集成log4net、NLog等日志框架,记录服务器启动、请求处理、错误信息等。
3. 网络分发(`NetDispatcher.cs`)

封装网络通信逻辑,支持客户端TCP连接管理、数据接收与分发,核心功能包括:

  • 异步Socket通信:基于SocketAsyncEventArgs(SAEA)实现高效IO,减少线程开销;
  • 数据帧解析:处理OPC UA标准TCP帧格式(如Hello/Acknowledge/ReverseHello帧);
  • 请求分发:将解析后的请求转发至Application类对应的处理方法(如读请求转发至HandleReadRequest)。

三、代码特色与可扩展方向

(一)代码核心特色

  1. 纯原生实现:未依赖任何OPC UA第三方库(如OPC Foundation UA .NET Stack),所有核心逻辑(协议、加密、地址空间)均手动实现,便于深度定制与问题排查。
  2. 规范兼容性:严格遵循OPC UA 1.04规范,支持标准节点模型、请求接口、安全策略,可与主流OPC UA客户端(如UA Expert、Kepware Client)无缝对接。
  3. 高性能设计
    - 地址空间基于ConcurrentDictionary实现,支持多线程并发访问;
    - 监控项队列基于ConcurrentQueue,避免锁竞争;
    - 网络通信基于SAEA模型,支持高并发客户端连接。
  4. 模块化架构:地址空间、安全、请求处理等模块独立封装,耦合度低,便于单独扩展与替换。

(二)关键可扩展方向

  1. 历史数据集成
    - 扩展HandleHistoryReadRequest:集成时序数据库,实现历史数据查询;
    - 扩展HandleHistoryUpdateRequest:支持历史数据补录、修改与删除;
    - 增加数据归档线程:定时将实时数据写入数据库,实现数据持久化。
  2. 设备连接扩展
    - 新增IDeviceDriver接口:定义设备数据读写方法;
    - 实现具体驱动:如Modbus TCP、S7协议驱动,将设备数据映射到OPC UA变量节点;
    - 扩展NodeVariable:增加DeviceAddress属性,关联设备寄存器地址。
  3. 安全增强
    - 扩展SessionValidateClientUser:支持LDAP、OAuth2.0等身份验证方式;
    - 增加证书吊销列表(CRL)验证:在SessionValidateClientApplication中检查客户端证书是否吊销;
    - 实现安全审计:通过ILogger记录安全事件(如登录失败、证书验证失败)。
  4. 跨平台支持
    - 迁移核心代码至.NET 6/8:替换Windows特有API(如CNG加密)为跨平台API(如System.Security.Cryptography跨平台实现);
    - 适配Linux/macOS:调整网络通信、文件路径相关逻辑,实现全平台部署。
  5. 监控与运维
    - 扩展ServerDiagnostics节点:增加CPU、内存占用、客户端连接数等监控指标;
    - 实现服务器配置界面:通过WinForms/WPF开发配置工具,支持地址空间编辑、安全策略配置;
    - 增加报警功能:扩展BaseEventType,实现服务器故障、客户端异常连接等报警事件。

四、使用示例与验证步骤

(一)基础使用流程

  1. 项目编译
    - 打开IcsRadeTech.OPC.Server.sln(需Visual Studio 2017及以上);
    - 选择Debug/Release模式,编译生成IcsRadeTech.API.dll
  2. 服务器启动
    csharp
    // 1. 创建服务器配置
    var serverConfig = new ServerConfig
    {
    EndpointUrl = "opc.tcp://localhost:4840/IcsRadeTech/OPCServer", // 服务器端点URL
    SecurityPolicy = SecurityPolicy.Basic256Sha256, // 安全策略
    MessageSecurityMode = MessageSecurityMode.SignAndEncrypt // 消息安全模式
    };
    // 2. 创建服务器实例
    var server = ServerFactory.CreateServer(serverConfig);
    // 3. 启动服务器
    server.Start();
    Console.WriteLine("OPC UA Server started. Endpoint: " + serverConfig.EndpointUrl);
    // 4. 等待关闭
    Console.ReadLine();
    server.Stop();
  3. 客户端连接验证
    - 使用UA Expert客户端,添加服务器端点(opc.tcp://localhost:4840/IcsRadeTech/OPCServer);
    - 浏览地址空间:查看Objects/Server节点下的ServerStatusServerCapabilities等子节点;
    - 读取节点值:读取ServerServerStatusState节点,验证返回值为Running
    - 订阅节点:创建监控项,修改节点值(需扩展写逻辑),验证客户端接收数据变化通知。

(二)核心功能验证点

功能模块 验证步骤 预期结果
地址空间浏览 客户端浏览Root/Objects/Server节点 显示ServerStatusServerCapabilities等子节点,节点类型正确
读请求 读取ServerServerStatusCurrentTime节点 返回当前服务器时间,状态码为Good
写请求 扩展写逻辑后,写入自定义变量节点(如ns=1;s=Temperature 节点值更新成功,返回Good;无权限时返回BadNotWritable
监控项 订阅Temperature节点,修改节点值 客户端收到数据变化通知,DataValue包含新值与时间戳
安全连接 使用Basic256Sha256策略+SignAndEncrypt模式连接 连接成功,抓包可见数据加密;证书无效时连接失败

五、总结

该C# OPC UA服务器端源码是一个轻量、规范、高可扩展的工业通信解决方案,通过纯原生代码实现了OPC UA的核心功能,包括地址空间管理、会话处理、安全加密、数据监控等。源码严格遵循OPC UA规范,可直接用于工业自动化、数据采集等场景,也可作为二次开发的基础框架,通过扩展设备驱动、历史数据、安全策略等模块,满足复杂工业场景需求。

C# OPC UA 服务器端源码 该源码未使用任何第三方支持库,纯代码实现

其核心价值在于:

  1. 无依赖限制:避免第三方库的版本锁定与功能限制,可根据项目需求灵活定制;
  2. 学习价值:完整展现OPC UA协议的底层实现(如地址空间模型、加密算法、请求处理),是学习OPC UA规范的优质案例;
  3. 工业适用性:支持标准安全策略与客户端交互,可与主流工业软件对接,解决工业设备“信息孤岛”问题。

对于需要构建定制化OPC UA服务器的开发者,该源码提供了完整的技术框架与实现思路,可大幅降低开发成本,缩短项目周期。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐