node-opcua-client 2.178.0 → 2.179.0
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.
- package/dist/alarms_and_conditions/client_alarm_tools.js +7 -5
- package/dist/alarms_and_conditions/client_alarm_tools.js.map +1 -1
- package/dist/alarms_and_conditions/client_tools.js +38 -28
- package/dist/alarms_and_conditions/client_tools.js.map +1 -1
- package/dist/client_base.js.map +1 -1
- package/dist/client_monitored_item.d.ts +1 -1
- package/dist/client_monitored_item.js +4 -2
- package/dist/client_monitored_item.js.map +1 -1
- package/dist/client_monitored_item_group.d.ts +4 -3
- package/dist/client_monitored_item_group.js +8 -5
- package/dist/client_monitored_item_group.js.map +1 -1
- package/dist/client_monitored_item_toolbox.js +4 -2
- package/dist/client_monitored_item_toolbox.js.map +1 -1
- package/dist/client_session.d.ts +9 -2
- package/dist/client_session_keepalive_manager.d.ts +1 -1
- package/dist/client_session_keepalive_manager.js +50 -29
- package/dist/client_session_keepalive_manager.js.map +1 -1
- package/dist/client_subscription.d.ts +2 -2
- package/dist/client_subscription.js +3 -1
- package/dist/client_subscription.js.map +1 -1
- package/dist/common.d.ts +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/opcua_client.js +1 -0
- package/dist/opcua_client.js.map +1 -1
- package/dist/private/client_base_impl.js +125 -65
- package/dist/private/client_base_impl.js.map +1 -1
- package/dist/private/client_monitored_item_group_impl.d.ts +1 -0
- package/dist/private/client_monitored_item_group_impl.js +6 -8
- package/dist/private/client_monitored_item_group_impl.js.map +1 -1
- package/dist/private/client_monitored_item_impl.js +0 -4
- package/dist/private/client_monitored_item_impl.js.map +1 -1
- package/dist/private/client_publish_engine.js +62 -28
- package/dist/private/client_publish_engine.js.map +1 -1
- package/dist/private/client_session_impl.d.ts +49 -17
- package/dist/private/client_session_impl.js +240 -143
- package/dist/private/client_session_impl.js.map +1 -1
- package/dist/private/client_subscription_impl.js +15 -12
- package/dist/private/client_subscription_impl.js.map +1 -1
- package/dist/private/i_private_client.d.ts +1 -1
- package/dist/private/opcua_client_impl.js +12 -10
- package/dist/private/opcua_client_impl.js.map +1 -1
- package/dist/private/reconnection/client_publish_engine_reconnection.js +17 -7
- package/dist/private/reconnection/client_publish_engine_reconnection.js.map +1 -1
- package/dist/private/reconnection/client_subscription_reconnection.js +11 -7
- package/dist/private/reconnection/client_subscription_reconnection.js.map +1 -1
- package/dist/private/reconnection/reconnection.js +31 -14
- package/dist/private/reconnection/reconnection.js.map +1 -1
- package/dist/reverse/client_reverse_connect.js.map +1 -1
- package/dist/tools/findservers.js.map +1 -1
- package/dist/tools/read_history_server_capabilities.d.ts +2 -1
- package/dist/tools/read_history_server_capabilities.js +6 -3
- package/dist/tools/read_history_server_capabilities.js.map +1 -1
- package/package.json +50 -50
- package/source/alarms_and_conditions/client_alarm_tools.ts +10 -8
- package/source/alarms_and_conditions/client_tools.ts +71 -30
- package/source/client_base.ts +0 -1
- package/source/client_monitored_item.ts +10 -9
- package/source/client_monitored_item_base.ts +2 -8
- package/source/client_monitored_item_group.ts +13 -10
- package/source/client_monitored_item_toolbox.ts +4 -2
- package/source/client_session.ts +10 -3
- package/source/client_session_keepalive_manager.ts +72 -55
- package/source/client_subscription.ts +6 -3
- package/source/common.ts +4 -0
- package/source/index.ts +1 -1
- package/source/opcua_client.ts +1 -0
- package/source/private/client_base_impl.ts +179 -102
- package/source/private/client_monitored_item_group_impl.ts +17 -18
- package/source/private/client_monitored_item_impl.ts +0 -4
- package/source/private/client_publish_engine.ts +78 -40
- package/source/private/client_session_impl.ts +393 -236
- package/source/private/client_subscription_impl.ts +20 -25
- package/source/private/i_private_client.ts +1 -1
- package/source/private/opcua_client_impl.ts +13 -10
- package/source/private/reconnection/client_publish_engine_reconnection.ts +22 -21
- package/source/private/reconnection/client_subscription_reconnection.ts +12 -8
- package/source/private/reconnection/reconnection.ts +35 -18
- package/source/reverse/client_reverse_connect.ts +11 -3
- package/source/tools/findservers.ts +0 -1
- package/source/tools/read_history_server_capabilities.ts +9 -7
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @module node-opcua-client
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { EventEmitter } from "node:events";
|
|
5
6
|
import chalk from "chalk";
|
|
6
|
-
import { EventEmitter } from "events";
|
|
7
7
|
import { assert } from "node-opcua-assert";
|
|
8
8
|
import { AttributeIds } from "node-opcua-basic-types";
|
|
9
9
|
import { ServerState } from "node-opcua-common";
|
|
@@ -11,20 +11,11 @@ import { VariableIds } from "node-opcua-constants";
|
|
|
11
11
|
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
|
-
import { ClientSecureChannelLayer } from "node-opcua-secure-channel";
|
|
15
|
-
import type { StatusCode } from "node-opcua-status-code";
|
|
14
|
+
import { ClientSecureChannelLayer, type ServiceFaultAnnotatedError } from "node-opcua-secure-channel";
|
|
16
15
|
import { StatusCodes } from "node-opcua-status-code";
|
|
17
16
|
import type { ClientSessionImpl } from "./private/client_session_impl";
|
|
18
17
|
import type { IClientBase } from "./private/i_private_client";
|
|
19
18
|
|
|
20
|
-
interface ServiceFaultAnnotatedError extends Error {
|
|
21
|
-
response?: {
|
|
22
|
-
responseHeader?: {
|
|
23
|
-
serviceResult?: StatusCode;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
19
|
const serverStatusStateNodeId = coerceNodeId(VariableIds.Server_ServerStatus_State);
|
|
29
20
|
|
|
30
21
|
const debugLog = make_debugLog(__filename);
|
|
@@ -86,26 +77,40 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
86
77
|
|
|
87
78
|
public stop(): void {
|
|
88
79
|
if (this.timerId) {
|
|
89
|
-
|
|
80
|
+
// c8 ignore next
|
|
81
|
+
doDebug && debugLog("ClientSessionKeepAliveManager#stop");
|
|
90
82
|
clearTimeout(this.timerId);
|
|
91
83
|
this.timerId = undefined;
|
|
92
84
|
} else {
|
|
93
|
-
|
|
85
|
+
// c8 ignore next
|
|
86
|
+
doDebug && debugLog("warning ClientSessionKeepAliveManager#stop ignore (already stopped)");
|
|
94
87
|
}
|
|
95
88
|
}
|
|
96
89
|
|
|
97
90
|
private ping_server() {
|
|
98
|
-
this._ping_server()
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
91
|
+
this._ping_server()
|
|
92
|
+
.catch((err) => {
|
|
93
|
+
// _ping_server must never reject: transactionInProgress would stay latched and the
|
|
94
|
+
// timer chain would stop, silently killing the keep-alive for the life of the
|
|
95
|
+
// session. Recover the cycle instead, and try again at the normal cadence.
|
|
96
|
+
warningLog(
|
|
97
|
+
chalk.cyan("ClientSessionKeepAliveManager#ping_server unexpected error "),
|
|
98
|
+
chalk.yellow(err instanceof Error ? err.message : String(err))
|
|
99
|
+
);
|
|
100
|
+
this.transactionInProgress = false;
|
|
101
|
+
return this.checkInterval;
|
|
102
|
+
})
|
|
103
|
+
.then((nextCheckDelay) => {
|
|
104
|
+
if (!this.session || this.session.hasBeenClosed()) {
|
|
105
|
+
return; // stop here
|
|
106
|
+
}
|
|
107
|
+
if (this.timerId) {
|
|
108
|
+
// _ping_server returns how long to wait before the next check: checkInterval
|
|
109
|
+
// in steady state, the residual wait when it skipped the ping because we heard
|
|
110
|
+
// from the server recently, or an explicit backoff after consecutive faults.
|
|
111
|
+
this.timerId = setTimeout(() => this.ping_server(), Math.max(1, nextCheckDelay));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
109
114
|
}
|
|
110
115
|
/**
|
|
111
116
|
* @private
|
|
@@ -117,45 +122,52 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
117
122
|
private async _ping_server(): Promise<number> {
|
|
118
123
|
const session = this.session;
|
|
119
124
|
if (!session || session.isReconnecting) {
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
// c8 ignore next
|
|
126
|
+
doDebug && debugLog("ClientSessionKeepAliveManager#ping_server => no session available");
|
|
127
|
+
return this.checkInterval;
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
if (!this.timerId) {
|
|
125
|
-
return
|
|
131
|
+
return this.checkInterval; // keep-alive has been canceled ....
|
|
126
132
|
}
|
|
127
133
|
const now = Date.now();
|
|
128
134
|
|
|
129
135
|
const timeSinceLastServerContact = now - session.lastResponseReceivedTime.getTime();
|
|
130
136
|
if (timeSinceLastServerContact < this.pingTimeout) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
// c8 ignore next
|
|
138
|
+
doDebug &&
|
|
139
|
+
debugLog(
|
|
140
|
+
"ClientSessionKeepAliveManager#ping_server skipped because last communication with server was not that long ago ping timeout=",
|
|
141
|
+
Math.round(this.pingTimeout),
|
|
142
|
+
"timeSinceLastServerContact = ",
|
|
143
|
+
timeSinceLastServerContact
|
|
144
|
+
);
|
|
145
|
+
// no need to send a ping yet: come back when the quiet period is actually over
|
|
146
|
+
return this.pingTimeout - timeSinceLastServerContact;
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
if (session.isReconnecting) {
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
// c8 ignore next
|
|
151
|
+
doDebug && debugLog("ClientSessionKeepAliveManager#ping_server skipped because client is reconnecting");
|
|
152
|
+
return this.checkInterval;
|
|
144
153
|
}
|
|
145
154
|
if (session.hasBeenClosed()) {
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
// c8 ignore next
|
|
156
|
+
doDebug && debugLog("ClientSessionKeepAliveManager#ping_server skipped because client is reconnecting");
|
|
157
|
+
return this.checkInterval;
|
|
148
158
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
159
|
+
// c8 ignore next
|
|
160
|
+
doDebug &&
|
|
161
|
+
debugLog(
|
|
162
|
+
"ClientSessionKeepAliveManager#ping_server timeSinceLastServerContact=",
|
|
163
|
+
timeSinceLastServerContact,
|
|
164
|
+
"timeout",
|
|
165
|
+
this.session.timeout
|
|
166
|
+
);
|
|
155
167
|
|
|
156
168
|
if (this.transactionInProgress) {
|
|
157
169
|
// readVariable already taking place ! Ignore
|
|
158
|
-
return
|
|
170
|
+
return this.checkInterval;
|
|
159
171
|
}
|
|
160
172
|
this.transactionInProgress = true;
|
|
161
173
|
// Server_ServerStatus_State
|
|
@@ -180,7 +192,7 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
180
192
|
"Keep alive has failed, considering a network outage is in place, forcing a reconnection"
|
|
181
193
|
);
|
|
182
194
|
terminateConnection(session._client);
|
|
183
|
-
resolve(
|
|
195
|
+
resolve(this.checkInterval);
|
|
184
196
|
} else {
|
|
185
197
|
if (sc?.equals(StatusCodes.BadInvalidTimestamp)) {
|
|
186
198
|
// BadInvalidTimestamp (OPC UA Part 4 7.38.2, Table 178:
|
|
@@ -204,9 +216,13 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
204
216
|
// See: https://reference.opcfoundation.org/Core/Part4/v105/docs/7.38.2
|
|
205
217
|
// https://reference.opcfoundation.org/Core/Part4/v105/docs/7.32
|
|
206
218
|
this.consecutiveFailures = 0;
|
|
207
|
-
|
|
219
|
+
// c8 ignore next
|
|
220
|
+
doDebug &&
|
|
221
|
+
debugLog(
|
|
222
|
+
"emit keepalive (BadInvalidTimestamp: session alive, clock skew on request timestamp)"
|
|
223
|
+
);
|
|
208
224
|
this.emit("keepalive", this.lastKnownState ?? ServerState.Unknown, this.count);
|
|
209
|
-
resolve(
|
|
225
|
+
resolve(this.checkInterval);
|
|
210
226
|
return;
|
|
211
227
|
}
|
|
212
228
|
this.consecutiveFailures++;
|
|
@@ -218,11 +234,11 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
218
234
|
this.emit("failure");
|
|
219
235
|
warningLog("Keep alive has failed, considering a network outage is in place, forcing a reconnection");
|
|
220
236
|
terminateConnection(session._client);
|
|
221
|
-
resolve(
|
|
237
|
+
resolve(this.checkInterval);
|
|
222
238
|
}
|
|
223
239
|
return;
|
|
224
240
|
}
|
|
225
|
-
if (!dataValue
|
|
241
|
+
if (!dataValue?.value) {
|
|
226
242
|
/**
|
|
227
243
|
* @event failure
|
|
228
244
|
* raised when the server is not responding or is responding with en error to
|
|
@@ -231,7 +247,7 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
231
247
|
this.emit("failure");
|
|
232
248
|
warningLog("Keep alive has failed, considering a network outage is in place, forcing a reconnection");
|
|
233
249
|
terminateConnection(session._client);
|
|
234
|
-
resolve(
|
|
250
|
+
resolve(this.checkInterval);
|
|
235
251
|
return;
|
|
236
252
|
}
|
|
237
253
|
|
|
@@ -250,9 +266,10 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
250
266
|
this.count++; // increase successful counter
|
|
251
267
|
}
|
|
252
268
|
this.consecutiveFailures = 0;
|
|
253
|
-
|
|
269
|
+
// c8 ignore next
|
|
270
|
+
doDebug && debugLog("emit keepalive");
|
|
254
271
|
this.emit("keepalive", this.lastKnownState, this.count);
|
|
255
|
-
resolve(
|
|
272
|
+
resolve(this.checkInterval);
|
|
256
273
|
}
|
|
257
274
|
);
|
|
258
275
|
});
|
|
@@ -262,7 +279,7 @@ export class ClientSessionKeepAliveManager extends EventEmitter implements Clien
|
|
|
262
279
|
function terminateConnection(client: IClientBase | null) {
|
|
263
280
|
if (!client) return;
|
|
264
281
|
|
|
265
|
-
const channel: ClientSecureChannelLayer =
|
|
282
|
+
const channel: ClientSecureChannelLayer | null = client._secureChannel;
|
|
266
283
|
if (!channel) {
|
|
267
284
|
return;
|
|
268
285
|
}
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* @module node-opcua-client
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
import type { EventEmitter } from "events";
|
|
5
|
+
import type { EventEmitter } from "node:events";
|
|
7
6
|
import type { Byte, Double, UInt32 } from "node-opcua-basic-types";
|
|
8
7
|
|
|
9
8
|
import type { DiagnosticInfo } from "node-opcua-data-model";
|
|
@@ -238,8 +237,10 @@ export interface ClientSubscription extends EventEmitter {
|
|
|
238
237
|
}
|
|
239
238
|
|
|
240
239
|
export declare interface ClientSubscription {
|
|
240
|
+
// biome-ignore lint/suspicious/noExplicitAny: matches Node's EventEmitter catch-all signature; narrowing to unknown[] breaks assignability of specifically-typed listener handlers at call sites
|
|
241
241
|
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
242
242
|
|
|
243
|
+
// biome-ignore lint/suspicious/noExplicitAny: matches Node's EventEmitter catch-all signature; narrowing to unknown[] breaks assignability of specifically-typed listener handlers at call sites
|
|
243
244
|
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
244
245
|
/**
|
|
245
246
|
* notify the observers that the subscription has now started
|
|
@@ -298,8 +299,10 @@ export declare interface ClientSubscription {
|
|
|
298
299
|
): ClientMonitoredItem;
|
|
299
300
|
}
|
|
300
301
|
|
|
302
|
+
// biome-ignore lint/suspicious/noUnsafeDeclarationMerging: interface adds typed members/overloads for this class
|
|
303
|
+
// biome-ignore lint/complexity/noStaticOnlyClass: class identity is required for the `implements IBasicSubscription` contract; static factory + static flag can't be expressed as a namespace
|
|
301
304
|
export class ClientSubscription implements IBasicSubscription {
|
|
302
|
-
public static create(
|
|
305
|
+
public static create(_clientSession: ClientSession, _options: ClientSubscriptionOptions): ClientSubscription {
|
|
303
306
|
/* c8 ignore next*/
|
|
304
307
|
throw new Error("Not Implemented");
|
|
305
308
|
}
|
package/source/common.ts
CHANGED
|
@@ -49,6 +49,8 @@ import type {
|
|
|
49
49
|
SetMonitoringModeResponse,
|
|
50
50
|
SetPublishingModeRequest,
|
|
51
51
|
SetPublishingModeResponse,
|
|
52
|
+
SetTriggeringRequest,
|
|
53
|
+
SetTriggeringResponse,
|
|
52
54
|
TransferSubscriptionsRequest,
|
|
53
55
|
TransferSubscriptionsResponse
|
|
54
56
|
} from "node-opcua-service-subscription";
|
|
@@ -80,6 +82,7 @@ export type Request =
|
|
|
80
82
|
| RepublishRequest
|
|
81
83
|
| DeleteMonitoredItemsRequest
|
|
82
84
|
| SetPublishingModeRequest
|
|
85
|
+
| SetTriggeringRequest
|
|
83
86
|
| FindServersOnNetworkRequest
|
|
84
87
|
| FindServersRequest
|
|
85
88
|
| HistoryReadRequest
|
|
@@ -110,6 +113,7 @@ export type Response =
|
|
|
110
113
|
| RepublishResponse
|
|
111
114
|
| DeleteMonitoredItemsResponse
|
|
112
115
|
| SetPublishingModeResponse
|
|
116
|
+
| SetTriggeringResponse
|
|
113
117
|
| FindServersOnNetworkResponse
|
|
114
118
|
| FindServersResponse
|
|
115
119
|
| HistoryReadResponse
|
package/source/index.ts
CHANGED
|
@@ -37,8 +37,8 @@ export * from "./client_session";
|
|
|
37
37
|
export * from "./client_subscription";
|
|
38
38
|
export * from "./client_utils";
|
|
39
39
|
export * from "./opcua_client";
|
|
40
|
-
export * from "./reverse/client_reverse_connect";
|
|
41
40
|
export { ClientSidePublishEngine } from "./private/client_publish_engine";
|
|
41
|
+
export * from "./reverse/client_reverse_connect";
|
|
42
42
|
export * from "./tools/findservers";
|
|
43
43
|
export * from "./tools/read_history_server_capabilities";
|
|
44
44
|
export * from "./user_identity_info";
|
package/source/opcua_client.ts
CHANGED
|
@@ -233,6 +233,7 @@ export interface OPCUAClient<Events extends OPCUAClientBaseEvents = OPCUAClientB
|
|
|
233
233
|
* });
|
|
234
234
|
* ```
|
|
235
235
|
*/
|
|
236
|
+
// biome-ignore lint/complexity/noStaticOnlyClass: interface merges instance-side typings; static factory + static accessors can't be expressed as a namespace (get/set)
|
|
236
237
|
export class OPCUAClient {
|
|
237
238
|
/**
|
|
238
239
|
* Create a new OPC UA client instance.
|