Architecture
Architecture
OpcSharp uses a layered architecture where each layer depends only on the layers below it.
Layer Stack
OpcSharp.Client ← High-level API (OpcSharpClient, OpcSharpClientBuilder, DI)
OpcSharp.Services ← Service wrappers (Attribute, Browse, Method, Subscription)
OpcSharp.Protocol ← Session + SecureChannel (framing, request/response, token renewal)
OpcSharp.Security ← Security policies, key derivation, crypto, certificates
OpcSharp.Transport.Http ← HTTPS/WebSocket transport
OpcSharp.Transport ← TCP transport (Hello/ACK, chunking, buffer negotiation)
OpcSharp.Encoding ← Binary encoder/decoder for all OPC UA types
OpcSharp.Types ← Core types (NodeId, StatusCode, DataValue, Variant, etc.)Key Interfaces
| Interface | Layer | Purpose |
|---|---|---|
IOpcSharpClient | Client | Top-level API for connecting, reading, writing, subscribing |
ISession | Protocol | Session lifecycle: Create, Activate, Close, SendRequest |
ISecureChannel | Protocol | Channel lifecycle: Open, Close, SendRequest, RenewToken |
ITransport | Transport | TCP connection and message framing |
Client Layer
The entry point for most users. OpcSharpClientBuilder provides a fluent API:
var client = new OpcSharpClientBuilder()
.WithEndpoint("opc.tcp://localhost:4840")
.WithSessionName("MySession")
.WithSecurity(SecurityPolicyUris.Basic256Sha256, MessageSecurityMode.SignAndEncrypt)
.WithUserIdentity(new UserNameIdentity("user", "pass"))
.WithAutoAcceptUntrustedCertificates(true)
.Build();ConnectAsync() creates the full stack: Transport -> SecureChannel -> Session -> Services.
Services Layer
Each service wraps a set of OPC UA service calls:
- IAttributeService —
ReadAsync(),WriteAsync() - IBrowseService —
BrowseAsync(),BrowseNextAsync(),TranslateBrowsePathsToNodeIdsAsync() - IMethodService —
CallAsync() - ISubscriptionService —
CreateSubscriptionAsync(),ModifySubscriptionAsync(),DeleteSubscriptionsAsync() - IMonitoredItemService —
CreateMonitoredItemsAsync(),ModifyMonitoredItemsAsync(),DeleteMonitoredItemsAsync() - IDiscoveryService —
FindServersAsync(),GetEndpointsAsync()
All services use Session.SendRequestAsync(typeId, body, ct) with manual binary encoding/decoding.
Protocol Layer
Manages the OPC UA session and secure channel:
- Session — CreateSession (TypeId=461), ActivateSession (TypeId=467), CloseSession
- SecureChannel — OpenSecureChannel (OPN message), message signing and encryption, token renewal at 75% lifetime
- State machines —
SessionStateandSecureChannelStateenums track lifecycle transitions
Transport Layer
Handles the TCP connection and OPC UA message framing:
- Hello/ACK handshake with buffer size negotiation
- Message chunking and reassembly (F=final, C=continuation)
- 8-byte message header:
[Type:3][F/C:1][Size:4] - Message types: HEL, ACK, ERR, MSG, OPN, CLO
Encoding Layer
Binary encoder/decoder for all OPC UA built-in types:
- NodeId (5 compressed encoding variants: TwoByte, FourByte, Numeric, String, Guid, Opaque)
- Variant (all 25 built-in types + arrays)
- DataValue (Value + StatusCode + timestamps)
- DateTime as Windows FILETIME (100ns intervals since Jan 1, 1601)
Types Layer
Core OPC UA type definitions used throughout the stack:
- Identifiers — NodeId, ExpandedNodeId, QualifiedName
- Values — Variant, DataValue, StatusCode
- Text — LocalizedText, DiagnosticInfo
- Extension — ExtensionObject (TypeId + Encoding + Body)
- Constants — AttributeIds, ObjectIds, DataTypeIds, ReferenceTypeIds