Node-opcua client takes too long to re-connect to the server

1.1k Views Asked by At

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}`);
  });
}
0

There are 0 best solutions below