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
|
-
|
|
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
|
|
122
|
-
|
|
123
|
-
|
|
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":";AAAA;;GAEG;;;;;;AAEH,kDAA0B;AAC1B,mCAAsC;AACtC,yDAA2C;AAC3C,mEAAsD;AACtD,yDAAgD;AAChD,+DAAmD;AAEnD,uDAAkF;AAClF,yDAAiD;AACjD,yEAAqE;
|
|
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.
|
|
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.
|
|
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.
|
|
25
|
-
"node-opcua-common": "2.
|
|
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.
|
|
29
|
-
"node-opcua-data-value": "2.
|
|
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.
|
|
39
|
-
"node-opcua-schemas": "2.
|
|
40
|
-
"node-opcua-secure-channel": "2.
|
|
41
|
-
"node-opcua-service-browse": "2.
|
|
42
|
-
"node-opcua-service-call": "2.
|
|
43
|
-
"node-opcua-service-discovery": "2.
|
|
44
|
-
"node-opcua-service-endpoints": "2.
|
|
45
|
-
"node-opcua-service-filter": "2.
|
|
46
|
-
"node-opcua-service-history": "2.
|
|
47
|
-
"node-opcua-service-query": "2.
|
|
48
|
-
"node-opcua-service-read": "2.
|
|
49
|
-
"node-opcua-service-register-node": "2.
|
|
50
|
-
"node-opcua-service-secure-channel": "2.
|
|
51
|
-
"node-opcua-service-session": "2.
|
|
52
|
-
"node-opcua-service-subscription": "2.
|
|
53
|
-
"node-opcua-service-translate-browse-path": "2.
|
|
54
|
-
"node-opcua-service-write": "2.
|
|
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.
|
|
56
|
+
"node-opcua-types": "2.170.0",
|
|
57
57
|
"node-opcua-utils": "2.169.0",
|
|
58
|
-
"node-opcua-variant": "2.
|
|
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.
|
|
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": "
|
|
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
|
-
|
|
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
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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);
|