OPC UA Client Proxy for Node.js
raw JSON →The `node-opcua-client-proxy` package is a specialized module within the comprehensive `node-opcua` pure Node.js OPC UA SDK, currently at version 2.169.0. It provides functionalities for creating client-side proxies to interact with OPC UA servers, facilitating streamlined machine-to-machine (M2M) and Internet of Things (IoT) communication patterns. The `node-opcua` project maintains an active release cadence, with frequent updates focusing on stability, performance, and OPC UA specification compliance (e.g., full support for OPC UA 1.05 subtyped structures and unions). Recent releases have introduced features like advertised endpoints for Docker/NAT deployments and a global method-call interceptor API, alongside significant internal migrations from older libraries (`async`/`lodash`) to native modern JavaScript. Key differentiators include its robust TypeScript support, comprehensive certificate management capabilities, and continuous optimization for memory and throughput, particularly in its secure channel and transport layers. This specific module is designed to provide a structured and potentially higher-level abstraction for client interactions with the OPC UA address space, simplifying common operations.
Common errors
error Error: self-signed certificate in certificate chain ↓
clientCertificateManager to explicitly trust the server's certificate. For development, you might temporarily set security mode to None, but this is not recommended for production environments. error Error: The provided endpoint is not supported ↓
endpointUrl is exact and corresponds to one advertised by the server. Use OPCUAClient.getEndpoints() to programmatically inspect available server endpoints and ensure your client's security settings (mode, policy) match a supported configuration. error TypeError: OPCUAClient is not a constructor ↓
import syntax (import { OPCUAClient } from 'node-opcua';) and that your Node.js project is configured to run ES Modules (e.g., by adding "type": "module" to your package.json or using .mjs file extensions). Warnings
breaking Core packages in `node-opcua` have undergone a significant migration from relying on external libraries like `async` and `lodash` to utilizing native modern JavaScript patterns. While `node-opcua-client-proxy` primarily exposes a higher-level API, direct reliance on or interaction with any underlying `async`/`lodash` utilities (e.g., for internal data structures or callbacks) might require code adjustments. ↓
gotcha The certificate management architecture has been extensively refactored, particularly for server-side components like `PushCertificateManagerServerImpl` and `OPCUACertificateManager`. While `node-opcua-client-proxy` is client-focused, clients interacting with servers using the updated certificate handling, especially via GDS push models or requiring full certificate chain trust, should verify their trust list configuration. ↓
gotcha Significant performance and memory optimizations have been applied to core transport, secure channel, and chunk manager layers. While these generally improve efficiency, custom low-level client configurations, or those relying on specific memory usage profiles or timing characteristics of older versions, might experience subtle behavioral changes or require re-tuning. ↓
breaking A bug fix in `v2.161.0` ensures that `historyRead` results correctly promote `OpaqueStructure` to `ExtensionObject` within `HistoryData`. If previous client logic had workarounds or incorrectly parsed `OpaqueStructure` from `historyRead` results, it will now receive the corrected `ExtensionObject` types, which could break existing data parsing. ↓
Install
npm install node-opcua-client-proxy yarn add node-opcua-client-proxy pnpm add node-opcua-client-proxy Imports
- OPCUAClient wrong
const OPCUAClient = require('node-opcua').OPCUAClientcorrectimport { OPCUAClient } from 'node-opcua' - ClientSession wrong
import { ClientSession } from 'node-opcua-client-proxy'correctimport { ClientSession } from 'node-opcua' - ClientProxy wrong
const { ClientProxy } = require('node-opcua-client-proxy')correctimport { ClientProxy } from 'node-opcua-client-proxy' - readVariableValue
import { readVariableValue } from 'node-opcua-client-proxy'
Quickstart
import { OPCUAClient, MessageSecurityMode, SecurityPolicy, ClientSession, TimestampsToReturn, AttributeIds } from 'node-opcua';
import { ClientProxy } from 'node-opcua-client-proxy';
const endpointUrl = process.env.OPCUA_ENDPOINT_URL ?? 'opc.tcp://localhost:4840';
const userIdentity = {
userName: process.env.OPCUA_USERNAME ?? 'user',
password: process.env.OPCUA_PASSWORD ?? 'password'
};
async function connectAndRead() {
const client = OPCUAClient.create({
endpointUrl: endpointUrl,
securityMode: MessageSecurityMode.None, // For demo purposes, consider stronger security in production
securityPolicy: SecurityPolicy.None,
// clientCertificateManager: provide a proper cert manager in production
connectionStrategy: { maxRetry: 5, initialDelay: 500, maxDelay: 3000 }
});
client.on('backoff', (retry, delay) => {
console.log(`Connection attempt failed. Retrying in ${delay / 1000}s (attempt ${retry})`);
});
let session: ClientSession | null = null;
try {
console.log(`Connecting to ${endpointUrl}...`);
await client.connect(endpointUrl);
console.log('Connected to OPC UA server.');
session = await client.createSession(userIdentity);
console.log(`Session created with id: ${session.sessionId.toString()}`);
// Instantiate the ClientProxy with the established session
const proxy = new ClientProxy(session);
// Example: Reading a specific node's value via the proxy (assuming proxy has a 'read' method)
const nodeIdToRead = 'ns=2;s=MyDevice/Temperature'; // Replace with a valid NodeId from your server
console.log(`Attempting to read NodeId: ${nodeIdToRead}`);
// Using session.read directly for now as proxy API is inferred
const dataValue = await session.read({
nodeId: nodeIdToRead,
attributeId: AttributeIds.Value,
timestampsToReturn: TimestampsToReturn.Both
});
if (dataValue.statusCode.isGood()) {
console.log(`Value of ${nodeIdToRead}: ${dataValue.value?.value} (Source Timestamp: ${dataValue.sourceTimestamp?.toISOString()})`);
} else {
console.error(`Failed to read ${nodeIdToRead}: ${dataValue.statusCode.toString()}`);
}
} catch (err) {
console.error('An error occurred during OPC UA communication:', err);
} finally {
if (session) {
await session.close();
console.log('Session closed.');
}
if (client) {
await client.disconnect();
console.log('Disconnected from OPC UA server.');
}
}
}
connectAndRead();