Skip to content
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

InterfaceLayerPurpose
IOpcSharpClientClientTop-level API for connecting, reading, writing, subscribing
ISessionProtocolSession lifecycle: Create, Activate, Close, SendRequest
ISecureChannelProtocolChannel lifecycle: Open, Close, SendRequest, RenewToken
ITransportTransportTCP 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:

  • IAttributeServiceReadAsync(), WriteAsync()
  • IBrowseServiceBrowseAsync(), BrowseNextAsync(), TranslateBrowsePathsToNodeIdsAsync()
  • IMethodServiceCallAsync()
  • ISubscriptionServiceCreateSubscriptionAsync(), ModifySubscriptionAsync(), DeleteSubscriptionsAsync()
  • IMonitoredItemServiceCreateMonitoredItemsAsync(), ModifyMonitoredItemsAsync(), DeleteMonitoredItemsAsync()
  • IDiscoveryServiceFindServersAsync(), 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 machinesSessionState and SecureChannelState enums 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