I'm using the node-opcua library to act as OPCUA client, connected to several external severs, not maintained by myself.
The connection is sometimes unstable and as a consequence the client loses the connection and will eventually try to repair the connection. Most of the time, the recovery is successful, however sometimes it's not.
When I asked the client about its internal state during the connection failure, I found out its internal state is panic and it currently reconnecting. And that's it. Nothing is gonna happen and the internal state will be panic forever. Re-connection failed and we also won't retry (or maybe the first try is still in progress / stuck at some point).
I found a log entry, which is maybe related to the repair-connection routine:
_repairConnection already in progress panic
I tried to gain a better understanding by analyzing related code (especially in client_base.impl.ts), but what I learned confused me even more.
From what I saw, I would expect, that we are in the panic state for only a very short time and switch afterwards to reconnecting and afterwards (depending on whether we were successful) to connected or disconnected. But how can it be, that I am stuck in the panic state ?
The goal is in the end to create subscriptions and react to value changes, and this is how it's done:
const client = OPCUAClient.create({
securityMode: MessageSecurityMode.None,
securityPolicy: SecurityPolicy.None,
endpointMustExist: false,
requestedSessionTimeout: 60000,
keepSessionAlive: true,
connectionStrategy: undefined
});
// adding some listeners
client.on(...);
await client.connect(<url>);
const session = await client.createSession({
userName: <userName>,
password: <password>,
type: UserTokenType.UserName
});
// adding some listeners
session.on(...);
const subscription = await session.createSubscription2({
requestedPublishingInterval: 1000,
requestedLifetimeCount: 1000,
requestedMaxKeepAliveCount: 10,
maxNotificationsPerPublish: 0,
publishingEnabled: true,
priority: 1
});
// adding some listeners
session.on(...);
const monitoredItems = await subscription.monitorItems(
[
{
nodeId: '...',
attributeId: AttributeIds.Value
},
{
nodeId: '...',
attributeId: AttributeIds.Value
}
],
{
samplingInterval: 1000,
discardOldest: true,
queueSize: 100
},
TimestampsToReturn.Both
);
// adding some listeners
monitoredItems.on('changed', (monitoredItem, dataValue) => {...});
I think this usage is pretty close to what I saw in node-opcua by example.
I'm using Node.js v16.16.0 and node-opcua v.2.117.0.