node-opcua-client 2.169.0 → 2.170.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,7 @@ import type { ClientSessionImpl } from "./private/client_session_impl";
7
7
  export interface ClientSessionKeepAliveManagerEvents {
8
8
  on(event: "keepalive", eventHandler: (lastKnownServerState: ServerState, count: number) => void): this;
9
9
  on(event: "failure", eventHandler: () => void): this;
10
+ on(event: "keepalive_failure", eventHandler: () => void): this;
10
11
  }
11
12
  export declare class ClientSessionKeepAliveManager extends EventEmitter implements ClientSessionKeepAliveManagerEvents {
12
13
  private readonly session;
@@ -14,6 +15,7 @@ export declare class ClientSessionKeepAliveManager extends EventEmitter implemen
14
15
  private pingTimeout;
15
16
  private lastKnownState?;
16
17
  private transactionInProgress;
18
+ private consecutiveFailures;
17
19
  count: number;
18
20
  checkInterval: number;
19
21
  constructor(session: ClientSessionImpl);
@@ -16,16 +16,19 @@ const node_opcua_constants_1 = require("node-opcua-constants");
16
16
  const node_opcua_debug_1 = require("node-opcua-debug");
17
17
  const node_opcua_nodeid_1 = require("node-opcua-nodeid");
18
18
  const node_opcua_secure_channel_1 = require("node-opcua-secure-channel");
19
+ const node_opcua_status_code_1 = require("node-opcua-status-code");
19
20
  const serverStatusStateNodeId = (0, node_opcua_nodeid_1.coerceNodeId)(node_opcua_constants_1.VariableIds.Server_ServerStatus_State);
20
21
  const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
21
22
  const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
22
23
  const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
24
+ const maxBackoffInterval = 60_000;
23
25
  class ClientSessionKeepAliveManager extends events_1.EventEmitter {
24
26
  session;
25
27
  timerId;
26
28
  pingTimeout;
27
29
  lastKnownState;
28
30
  transactionInProgress = false;
31
+ consecutiveFailures = 0;
29
32
  count = 0;
30
33
  checkInterval;
31
34
  constructor(session) {
@@ -69,7 +72,9 @@ class ClientSessionKeepAliveManager extends events_1.EventEmitter {
69
72
  return; // stop here
70
73
  }
71
74
  if (this.timerId) {
72
- const timeout = Math.max(1, this.checkInterval - delta);
75
+ // When delta exceeds checkInterval it is an explicit backoff requested by _ping_server;
76
+ // otherwise delta is the time already consumed this cycle.
77
+ const timeout = delta > this.checkInterval ? delta : Math.max(1, this.checkInterval - delta);
73
78
  this.timerId = setTimeout(() => this.ping_server(), timeout);
74
79
  }
75
80
  });
@@ -118,17 +123,39 @@ class ClientSessionKeepAliveManager extends events_1.EventEmitter {
118
123
  attributeId: node_opcua_basic_types_1.AttributeIds.Value
119
124
  }, (err, dataValue) => {
120
125
  this.transactionInProgress = false;
121
- if (err || !dataValue || !dataValue.value) {
122
- if (err) {
123
- warningLog(chalk_1.default.cyan(" warning : ClientSessionKeepAliveManager#ping_server "), chalk_1.default.yellow(err.message));
126
+ if (err) {
127
+ warningLog(chalk_1.default.cyan(" warning : ClientSessionKeepAliveManager#ping_server "), chalk_1.default.yellow(err.message));
128
+ const serviceFaultResponse = err.response;
129
+ if (serviceFaultResponse) {
130
+ const sc = serviceFaultResponse.responseHeader?.serviceResult;
131
+ if (sc?.equals(node_opcua_status_code_1.StatusCodes.BadSessionIdInvalid) || sc?.equals(node_opcua_status_code_1.StatusCodes.BadSessionClosed)) {
132
+ this.emit("failure");
133
+ warningLog("Keep alive has failed, considering a network outage is in place, forcing a reconnection");
134
+ terminateConnection(session._client);
135
+ resolve(0);
136
+ }
137
+ else {
138
+ this.consecutiveFailures++;
139
+ warningLog("Keep alive received ServiceFault from server (session intact):", sc?.toString());
140
+ this.emit("keepalive_failure");
141
+ resolve(Math.min(this.checkInterval * 2 ** this.consecutiveFailures, maxBackoffInterval));
142
+ }
124
143
  }
144
+ else {
145
+ this.emit("failure");
146
+ warningLog("Keep alive has failed, considering a network outage is in place, forcing a reconnection");
147
+ terminateConnection(session._client);
148
+ resolve(0);
149
+ }
150
+ return;
151
+ }
152
+ if (!dataValue || !dataValue.value) {
125
153
  /**
126
154
  * @event failure
127
155
  * raised when the server is not responding or is responding with en error to
128
156
  * the keep alive read Variable value transaction
129
157
  */
130
158
  this.emit("failure");
131
- // also simulate a connection by closing the channel abruptly from our end ...
132
159
  warningLog("Keep alive has failed, considering a network outage is in place, forcing a reconnection");
133
160
  terminateConnection(session._client);
134
161
  resolve(0);
@@ -143,6 +170,7 @@ class ClientSessionKeepAliveManager extends events_1.EventEmitter {
143
170
  this.lastKnownState = newState;
144
171
  this.count++; // increase successful counter
145
172
  }
173
+ this.consecutiveFailures = 0;
146
174
  debugLog("emit keepalive");
147
175
  this.emit("keepalive", this.lastKnownState, this.count);
148
176
  resolve(0);
@@ -1 +1 @@
1
- {"version":3,"file":"client_session_keepalive_manager.js","sourceRoot":"","sources":["../source/client_session_keepalive_manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client_session_keepalive_manager.js","sourceRoot":"","sources":["../source/client_session_keepalive_manager.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-client",
3
- "version": "2.169.0",
3
+ "version": "2.170.1",
4
4
  "description": "pure nodejs OPCUA SDK - module client",
5
5
  "scripts": {
6
6
  "clean": "npx rimraf -g node_modules dist *.tsbuildinfo certificates",
@@ -16,17 +16,17 @@
16
16
  "dependencies": {
17
17
  "@ster5/global-mutex": "^3.3.0",
18
18
  "chalk": "4.1.2",
19
- "node-opcua-alarm-condition": "2.169.0",
19
+ "node-opcua-alarm-condition": "2.170.1",
20
20
  "node-opcua-assert": "2.164.0",
21
21
  "node-opcua-basic-types": "2.169.0",
22
22
  "node-opcua-buffer-utils": "2.169.0",
23
23
  "node-opcua-certificate-manager": "2.169.0",
24
- "node-opcua-client-dynamic-extension-object": "2.169.0",
25
- "node-opcua-common": "2.169.0",
24
+ "node-opcua-client-dynamic-extension-object": "2.170.1",
25
+ "node-opcua-common": "2.170.0",
26
26
  "node-opcua-constants": "2.157.0",
27
27
  "node-opcua-crypto": "5.3.5",
28
- "node-opcua-data-model": "2.169.0",
29
- "node-opcua-data-value": "2.169.0",
28
+ "node-opcua-data-model": "2.170.0",
29
+ "node-opcua-data-value": "2.170.0",
30
30
  "node-opcua-date-time": "2.169.0",
31
31
  "node-opcua-debug": "2.168.0",
32
32
  "node-opcua-extension-object": "2.169.0",
@@ -35,32 +35,32 @@
35
35
  "node-opcua-numeric-range": "2.169.0",
36
36
  "node-opcua-object-registry": "2.169.0",
37
37
  "node-opcua-pki": "6.13.0",
38
- "node-opcua-pseudo-session": "2.169.0",
39
- "node-opcua-schemas": "2.169.0",
40
- "node-opcua-secure-channel": "2.169.0",
41
- "node-opcua-service-browse": "2.169.0",
42
- "node-opcua-service-call": "2.169.0",
43
- "node-opcua-service-discovery": "2.169.0",
44
- "node-opcua-service-endpoints": "2.169.0",
45
- "node-opcua-service-filter": "2.169.0",
46
- "node-opcua-service-history": "2.169.0",
47
- "node-opcua-service-query": "2.169.0",
48
- "node-opcua-service-read": "2.169.0",
49
- "node-opcua-service-register-node": "2.169.0",
50
- "node-opcua-service-secure-channel": "2.169.0",
51
- "node-opcua-service-session": "2.169.0",
52
- "node-opcua-service-subscription": "2.169.0",
53
- "node-opcua-service-translate-browse-path": "2.169.0",
54
- "node-opcua-service-write": "2.169.0",
38
+ "node-opcua-pseudo-session": "2.170.1",
39
+ "node-opcua-schemas": "2.170.0",
40
+ "node-opcua-secure-channel": "2.170.1",
41
+ "node-opcua-service-browse": "2.170.0",
42
+ "node-opcua-service-call": "2.170.0",
43
+ "node-opcua-service-discovery": "2.170.0",
44
+ "node-opcua-service-endpoints": "2.170.0",
45
+ "node-opcua-service-filter": "2.170.1",
46
+ "node-opcua-service-history": "2.170.0",
47
+ "node-opcua-service-query": "2.170.0",
48
+ "node-opcua-service-read": "2.170.0",
49
+ "node-opcua-service-register-node": "2.170.0",
50
+ "node-opcua-service-secure-channel": "2.170.0",
51
+ "node-opcua-service-session": "2.170.0",
52
+ "node-opcua-service-subscription": "2.170.1",
53
+ "node-opcua-service-translate-browse-path": "2.170.0",
54
+ "node-opcua-service-write": "2.170.0",
55
55
  "node-opcua-status-code": "2.169.0",
56
- "node-opcua-types": "2.169.0",
56
+ "node-opcua-types": "2.170.0",
57
57
  "node-opcua-utils": "2.169.0",
58
- "node-opcua-variant": "2.169.0",
58
+ "node-opcua-variant": "2.170.0",
59
59
  "thenify-ex": "4.4.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "dequeue": "^1.0.5",
63
- "node-opcua-address-space": "2.169.0",
63
+ "node-opcua-address-space": "2.170.1",
64
64
  "node-opcua-binary-stream": "2.169.0",
65
65
  "node-opcua-factory": "2.169.0",
66
66
  "node-opcua-leak-detector": "2.169.0",
@@ -86,7 +86,7 @@
86
86
  "internet of things"
87
87
  ],
88
88
  "homepage": "http://node-opcua.github.io/",
89
- "gitHead": "82d570d3e95bea689cbbe30096279885c5282245",
89
+ "gitHead": "40629feaff284ba70596149e58b3cc2a7a0e8f68",
90
90
  "files": [
91
91
  "dist",
92
92
  "source"
@@ -12,9 +12,19 @@ import type { DataValue } from "node-opcua-data-value";
12
12
  import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
13
13
  import { coerceNodeId } from "node-opcua-nodeid";
14
14
  import { ClientSecureChannelLayer } from "node-opcua-secure-channel";
15
+ import type { StatusCode } from "node-opcua-status-code";
16
+ import { StatusCodes } from "node-opcua-status-code";
15
17
  import type { ClientSessionImpl } from "./private/client_session_impl";
16
18
  import type { IClientBase } from "./private/i_private_client";
17
19
 
20
+ interface ServiceFaultAnnotatedError extends Error {
21
+ response?: {
22
+ responseHeader?: {
23
+ serviceResult?: StatusCode;
24
+ };
25
+ };
26
+ }
27
+
18
28
  const serverStatusStateNodeId = coerceNodeId(VariableIds.Server_ServerStatus_State);
19
29
 
20
30
  const debugLog = make_debugLog(__filename);
@@ -24,14 +34,18 @@ const warningLog = make_warningLog(__filename);
24
34
  export interface ClientSessionKeepAliveManagerEvents {
25
35
  on(event: "keepalive", eventHandler: (lastKnownServerState: ServerState, count: number) => void): this;
26
36
  on(event: "failure", eventHandler: () => void): this;
37
+ on(event: "keepalive_failure", eventHandler: () => void): this;
27
38
  }
28
39
 
40
+ const maxBackoffInterval = 60_000;
41
+
29
42
  export class ClientSessionKeepAliveManager extends EventEmitter implements ClientSessionKeepAliveManagerEvents {
30
43
  private readonly session: ClientSessionImpl;
31
44
  private timerId?: NodeJS.Timeout;
32
45
  private pingTimeout: number;
33
46
  private lastKnownState?: ServerState;
34
47
  private transactionInProgress = false;
48
+ private consecutiveFailures = 0;
35
49
  public count = 0;
36
50
  public checkInterval: number;
37
51
 
@@ -86,7 +100,9 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
86
100
  return; // stop here
87
101
  }
88
102
  if (this.timerId) {
89
- const timeout = Math.max(1, this.checkInterval - delta);
103
+ // When delta exceeds checkInterval it is an explicit backoff requested by _ping_server;
104
+ // otherwise delta is the time already consumed this cycle.
105
+ const timeout = delta > this.checkInterval ? delta : Math.max(1, this.checkInterval - delta);
90
106
  this.timerId = setTimeout(() => this.ping_server(), timeout);
91
107
  }
92
108
  });
@@ -153,25 +169,41 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
153
169
  (err: Error | null, dataValue?: DataValue) => {
154
170
  this.transactionInProgress = false;
155
171
 
156
- if (err || !dataValue || !dataValue.value) {
157
- if (err) {
158
- warningLog(
159
- chalk.cyan(" warning : ClientSessionKeepAliveManager#ping_server "),
160
- chalk.yellow(err.message)
161
- );
172
+ if (err) {
173
+ warningLog(chalk.cyan(" warning : ClientSessionKeepAliveManager#ping_server "), chalk.yellow(err.message));
174
+ const serviceFaultResponse = (err as ServiceFaultAnnotatedError).response;
175
+ if (serviceFaultResponse) {
176
+ const sc = serviceFaultResponse.responseHeader?.serviceResult;
177
+ if (sc?.equals(StatusCodes.BadSessionIdInvalid) || sc?.equals(StatusCodes.BadSessionClosed)) {
178
+ this.emit("failure");
179
+ warningLog(
180
+ "Keep alive has failed, considering a network outage is in place, forcing a reconnection"
181
+ );
182
+ terminateConnection(session._client);
183
+ resolve(0);
184
+ } else {
185
+ this.consecutiveFailures++;
186
+ warningLog("Keep alive received ServiceFault from server (session intact):", sc?.toString());
187
+ this.emit("keepalive_failure");
188
+ resolve(Math.min(this.checkInterval * 2 ** this.consecutiveFailures, maxBackoffInterval));
189
+ }
190
+ } else {
191
+ this.emit("failure");
192
+ warningLog("Keep alive has failed, considering a network outage is in place, forcing a reconnection");
193
+ terminateConnection(session._client);
194
+ resolve(0);
162
195
  }
196
+ return;
197
+ }
198
+ if (!dataValue || !dataValue.value) {
163
199
  /**
164
200
  * @event failure
165
201
  * raised when the server is not responding or is responding with en error to
166
202
  * the keep alive read Variable value transaction
167
203
  */
168
204
  this.emit("failure");
169
-
170
- // also simulate a connection by closing the channel abruptly from our end ...
171
205
  warningLog("Keep alive has failed, considering a network outage is in place, forcing a reconnection");
172
-
173
206
  terminateConnection(session._client);
174
-
175
207
  resolve(0);
176
208
  return;
177
209
  }
@@ -190,6 +222,7 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
190
222
  this.lastKnownState = newState;
191
223
  this.count++; // increase successful counter
192
224
  }
225
+ this.consecutiveFailures = 0;
193
226
  debugLog("emit keepalive");
194
227
  this.emit("keepalive", this.lastKnownState, this.count);
195
228
  resolve(0);