Using package node-opcua version 2.14.0 (found at: https://github.com/node-opcua) I have created a simple client that will connect to a server, create a session and create a subscription to listen for value changes.
The problem I'm experimenting is that when the connection is lost the node-opcua client seems to take a very long time to succesfully reconnect to the server and resume the subscription.
When I force the disconnection (turning off wifi for exampl) the following happens:
1. Subscription messages stop comming from the server 2. About 60 seconds later the "timed_out_request" event fires with many messages like:
requestHeader: RequestHeader {
authenticationToken: NodeId { identifierType: 1, value: 4213157730, namespace: 0 },
timestamp: 2020-09-09T14:49:46.851Z { high_low: [Array], picoseconds: 0 },
requestHandle: 24,
returnDiagnostics: 0,
auditEntryId: '',
timeoutHint: 50000,
additionalHeader: null
},
subscriptionAcknowledgements: [
SubscriptionAcknowledgement {
subscriptionId: 4265258243,
sequenceNumber: 13
}
]
}
NOTE: The 'close' event doesn't seem to fire!
I then re-connect the network, and this will happen:
1. Other network clients on my computer will re-connect and continue working (example, youtube, MQTT client, Data Base clients, etc) 2. The node-opcua client will keep receiving 'timed_out_request' events with the same message type 3. About 5 minutes later, the 'start_reconnection' event will fire 4. The node-opcua client will re-connect to the server and resume the subscription
Is there any way I can set the node-opcua client to re-connect faster once the connection is resumed?
Thanks in advance!
This is my client:
import { OPCUAClient,
MessageSecurityMode,
SecurityPolicy,
OPCUAClientOptions,
ClientSubscription,
DataValue,
ClientMonitoredItem,
ReadValueIdLike,
MonitoringParametersOptions,
AttributeIds,
TimestampsToReturn
} from 'node-opcua';
// Server connection
const connectionStrategy = {
initialDelay: 1000,
maxRetry: 1,
};
const options: OPCUAClientOptions = {
applicationName: 'AppName',
connectionStrategy: connectionStrategy,
securityMode: MessageSecurityMode.None,
securityPolicy: SecurityPolicy.None,
endpoint_must_exist: false,
};
const url = 'opc.tcp://opcuaserver.com:48010';
async function main() {
console.log('> Connecting...');
const client = OPCUAClient.create(options);
await client.connect(url);
console.log('> Connected !');
try {
// Create session
console.log('> Creating session...');
const session = await client.createSession();
console.log('> Session created !');
// Catch changes in the connection status
attachEventListeners(client);
// Create a subscription
initSubscription(client, session);
} catch (e) {
console.log(`couldn't create opcua session. error: ${e}`);
}
}
main().catch().then(()=> console.log('process finished'));
function attachEventListeners(client) {
client.on("start_reconnection", () => {
console.log(`> Starting reconnection...`);
})
.on("connection_reestablished", () => {
console.log(`> Connection reestablished !`);
})
.on("connection_failed", (e) => {
console.log(`> Connection failed !`, e);
})
.on("reconnection_attempt_has_failed", (e) => {
console.log(`> Re-connection attempt has failed !`, e);
})
.on("close", () => {
console.log(`> Connection closed !`);
})
.on("backoff", () => {
console.log(`> Connection backoff !`);
})
.on("after_reconnection", (err) => {
console.log( "> Reconnection process has been completed: ", err );
})
.on("timed_out_request", (request) => {
console.log( "> Request has timed out without receiving a response:", request);
});
}
function initSubscription(client, session) {
const subscription = ClientSubscription.create(session, {
requestedPublishingInterval: 10,
requestedLifetimeCount: 10,
requestedMaxKeepAliveCount: 2,
maxNotificationsPerPublish: 10,
publishingEnabled: true,
priority: 10,
});
subscription.on("keepalive", (x) => {
console.log("> Subscription > Keepalive", x);
})
.on("terminated", () => {
console.log("> Subscription > Terminated");
});
// Subscribe to "Air Conditioner Humidity" sensor
const itemToMonitor: ReadValueIdLike = {
nodeId: "ns=3;s=AirConditioner_6.Humidity",
attributeId: AttributeIds.Value
};
const parameters: MonitoringParametersOptions = {
samplingInterval: 10,
discardOldest: true,
queueSize: 10
};
const monitoredItem = ClientMonitoredItem.create(
subscription,
itemToMonitor,
parameters,
TimestampsToReturn.Both
);
monitoredItem.on("err", (err) => {
console.log(`subscribed resource error: ${err}`);
});
monitoredItem.on("changed", (value: DataValue) => {
console.log(`subscribed resource changed value: ${value.value.value}`);
});
}