C# OPC UA 服务器端纯代码实现源码
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),可根据部署需求开启。 - 依赖引用:除系统基础库(如
System、System.Core、System.Net.Http)外,还引入Newtonsoft.Json(用于JSON数据处理)、System.Buffers/System.Memory(内存优化)等,所有第三方库通过本地路径或NuGet包管理,确保部署独立性。
(二)代码文件组织
项目核心代码集中在IcsRadeTech.API.OpcServer命名空间下,按功能划分为多个子模块,共111个文件,关键文件与职责如下表:
| 核心文件/目录 | 所在路径 | 核心职责 |
|---|---|---|
AddressSpace.cs |
OpcServer/ |
定义地址空间节点模型、节点关系管理、地址空间初始化 |
Application.cs |
OpcServer/ |
服务器会话管理、请求处理(读/写/浏览)、监控项与事件通知逻辑 |
Security.cs及Cryptography子目录 |
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定义节点间引用的类型(如Organizes、HasTypeDefinition)。
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/uaSDK2、http://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.Object、NodeClass.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. 根据RelativePath的ReferenceTypeId(引用类型ID)、TargetName(目标名)匹配子节点,若匹配失败,返回StatusCode.BadNoMatch;
3. 成功匹配后,返回目标节点ID与剩余路径索引(RemainingPathIndex)。 - 历史数据请求:
HandleHistoryReadRequest/HandleHistoryUpdateRequest/HandleHistoryEventReadRequest:默认返回StatusCode.BadNotImplemented,可扩展集成时序数据库(如InfluxDB、TimescaleDB)实现历史数据读写。
3. 监控项与事件通知
代码通过“监控项-订阅”模型实现数据变化与事件通知,核心逻辑如下:
- 监控项管理:
MonitorAdd:检查节点存在性与访问权限后,将MonitoredItem加入monitorMap(键为ServerMonitorKey,由NodeId与AttributeId组成);MonitorRemove:从monitorMap中移除指定MonitoredItem,释放监控资源;- 数据变化通知(
MonitorNotifyDataChange):
1. 当节点值变化时,构建DataValue对象(包含新值与状态码);
2. 根据NodeId与NodeAttribute.Value构建ServerMonitorKey,从monitorMap获取关联的MonitoredItem列表;
3. 将DataValue加入MonitoredItem.QueueData队列,若队列溢出(超过QueueSize),设置QueueOverflowed=true;
4. 标记订阅的ChangeNotification为AtPublish,客户端通过Publish请求获取变化数据; - 事件通知(
MonitorNotifyEvent):逻辑与数据变化通知类似,将EventNotification加入MonitoredItem.QueueEvent队列,支持设备故障、系统状态变化等事件的分发。
(三)安全模块:加密与证书管理
安全是OPC UA的核心特性,代码通过Security.cs及Cryptography子目录实现完整的安全机制,覆盖数据加密、签名验证、证书管理等场景。
1. 加密算法实现
代码基于Windows Crypto API(CNG)实现多种加密算法,避免第三方库依赖,核心实现如下:
- 对称加密:
AesCng:封装AES加密算法,支持BCrypt底层API,提供加密/解密方法;TripleDESCng:实现三重DES加密,兼容旧版OPC UA客户端;- 非对称加密:
RSACng:基于CNG实现RSA算法,支持密钥生成、签名、加密操作,用于客户端身份验证与密钥交换;- 哈希与HMAC:
HMACSHA256Cng/HMACSHA384Cng/HMACSHA512Cng:基于CNG的HMAC哈希算法,用于数据完整性校验;BCryptHMAC:封装BCryptHMAC 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编码,支持数据类型的序列化与反序列化,核心功能包括:
- 基础类型编码:如
Boolean、Int32、String、DateTime等类型的二进制打包; - 复杂类型编码:如
NodeId、QualifiedName、LocalizedText、DataValue等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)。
三、代码特色与可扩展方向
(一)代码核心特色
- 纯原生实现:未依赖任何OPC UA第三方库(如OPC Foundation UA .NET Stack),所有核心逻辑(协议、加密、地址空间)均手动实现,便于深度定制与问题排查。
- 规范兼容性:严格遵循OPC UA 1.04规范,支持标准节点模型、请求接口、安全策略,可与主流OPC UA客户端(如UA Expert、Kepware Client)无缝对接。
- 高性能设计:
- 地址空间基于ConcurrentDictionary实现,支持多线程并发访问;
- 监控项队列基于ConcurrentQueue,避免锁竞争;
- 网络通信基于SAEA模型,支持高并发客户端连接。 - 模块化架构:地址空间、安全、请求处理等模块独立封装,耦合度低,便于单独扩展与替换。
(二)关键可扩展方向
- 历史数据集成:
- 扩展HandleHistoryReadRequest:集成时序数据库,实现历史数据查询;
- 扩展HandleHistoryUpdateRequest:支持历史数据补录、修改与删除;
- 增加数据归档线程:定时将实时数据写入数据库,实现数据持久化。 - 设备连接扩展:
- 新增IDeviceDriver接口:定义设备数据读写方法;
- 实现具体驱动:如Modbus TCP、S7协议驱动,将设备数据映射到OPC UA变量节点;
- 扩展NodeVariable:增加DeviceAddress属性,关联设备寄存器地址。 - 安全增强:
- 扩展SessionValidateClientUser:支持LDAP、OAuth2.0等身份验证方式;
- 增加证书吊销列表(CRL)验证:在SessionValidateClientApplication中检查客户端证书是否吊销;
- 实现安全审计:通过ILogger记录安全事件(如登录失败、证书验证失败)。 - 跨平台支持:
- 迁移核心代码至.NET 6/8:替换Windows特有API(如CNG加密)为跨平台API(如System.Security.Cryptography跨平台实现);
- 适配Linux/macOS:调整网络通信、文件路径相关逻辑,实现全平台部署。 - 监控与运维:
- 扩展ServerDiagnostics节点:增加CPU、内存占用、客户端连接数等监控指标;
- 实现服务器配置界面:通过WinForms/WPF开发配置工具,支持地址空间编辑、安全策略配置;
- 增加报警功能:扩展BaseEventType,实现服务器故障、客户端异常连接等报警事件。
四、使用示例与验证步骤
(一)基础使用流程
- 项目编译:
- 打开IcsRadeTech.OPC.Server.sln(需Visual Studio 2017及以上);
- 选择Debug/Release模式,编译生成IcsRadeTech.API.dll; - 服务器启动:
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(); - 客户端连接验证:
- 使用UA Expert客户端,添加服务器端点(opc.tcp://localhost:4840/IcsRadeTech/OPCServer);
- 浏览地址空间:查看Objects/Server节点下的ServerStatus、ServerCapabilities等子节点;
- 读取节点值:读取ServerServerStatusState节点,验证返回值为Running;
- 订阅节点:创建监控项,修改节点值(需扩展写逻辑),验证客户端接收数据变化通知。
(二)核心功能验证点
| 功能模块 | 验证步骤 | 预期结果 |
|---|---|---|
| 地址空间浏览 | 客户端浏览Root/Objects/Server节点 |
显示ServerStatus、ServerCapabilities等子节点,节点类型正确 |
| 读请求 | 读取ServerServerStatusCurrentTime节点 |
返回当前服务器时间,状态码为Good |
| 写请求 | 扩展写逻辑后,写入自定义变量节点(如ns=1;s=Temperature) |
节点值更新成功,返回Good;无权限时返回BadNotWritable |
| 监控项 | 订阅Temperature节点,修改节点值 |
客户端收到数据变化通知,DataValue包含新值与时间戳 |
| 安全连接 | 使用Basic256Sha256策略+SignAndEncrypt模式连接 |
连接成功,抓包可见数据加密;证书无效时连接失败 |
五、总结
该C# OPC UA服务器端源码是一个轻量、规范、高可扩展的工业通信解决方案,通过纯原生代码实现了OPC UA的核心功能,包括地址空间管理、会话处理、安全加密、数据监控等。源码严格遵循OPC UA规范,可直接用于工业自动化、数据采集等场景,也可作为二次开发的基础框架,通过扩展设备驱动、历史数据、安全策略等模块,满足复杂工业场景需求。

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

其核心价值在于:
- 无依赖限制:避免第三方库的版本锁定与功能限制,可根据项目需求灵活定制;
- 学习价值:完整展现OPC UA协议的底层实现(如地址空间模型、加密算法、请求处理),是学习OPC UA规范的优质案例;
- 工业适用性:支持标准安全策略与客户端交互,可与主流工业软件对接,解决工业设备“信息孤岛”问题。
对于需要构建定制化OPC UA服务器的开发者,该源码提供了完整的技术框架与实现思路,可大幅降低开发成本,缩短项目周期。


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


所有评论(0)