How does my OPCUAClient get stuck in "panic" state?

62 views Asked by At

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.

0

There are 0 answers