node-opcua-client 2.100.0 → 2.101.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/private/client_base_impl.d.ts +2 -1
- package/dist/private/client_base_impl.js +35 -30
- package/dist/private/client_base_impl.js.map +1 -1
- package/dist/private/client_session_impl.d.ts +1 -0
- package/dist/private/client_session_impl.js +21 -12
- package/dist/private/client_session_impl.js.map +1 -1
- package/dist/private/i_private_client.d.ts +1 -0
- package/dist/private/opcua_client_impl.js +1 -3
- package/dist/private/opcua_client_impl.js.map +1 -1
- package/dist/reconnection.js +12 -7
- package/dist/reconnection.js.map +1 -1
- package/package.json +8 -11
- package/source/private/client_base_impl.ts +42 -44
- package/source/private/client_session_impl.ts +26 -20
- package/source/private/i_private_client.ts +2 -0
- package/source/private/opcua_client_impl.ts +10 -13
- package/source/reconnection.ts +11 -7
|
@@ -69,13 +69,11 @@ import { performCertificateSanityCheck } from "../verify";
|
|
|
69
69
|
import { ClientSessionImpl } from "./client_session_impl";
|
|
70
70
|
import { IClientBase } from "./i_private_client";
|
|
71
71
|
|
|
72
|
-
// tslint:disable-next-line:no-var-requires
|
|
73
|
-
const once = require("once");
|
|
74
|
-
|
|
75
72
|
const debugLog = make_debugLog(__filename);
|
|
76
73
|
const doDebug = checkDebugFlag(__filename);
|
|
77
74
|
const errorLog = make_errorLog(__filename);
|
|
78
75
|
const warningLog = make_warningLog(__filename);
|
|
76
|
+
const traceInternalState = false;
|
|
79
77
|
|
|
80
78
|
const defaultConnectionStrategy: ConnectionStrategyOptions = {
|
|
81
79
|
initialDelay: 1000,
|
|
@@ -268,6 +266,7 @@ type InternalClientState =
|
|
|
268
266
|
| "disconnected"
|
|
269
267
|
| "connecting"
|
|
270
268
|
| "connected"
|
|
269
|
+
| "panic"
|
|
271
270
|
| "reconnecting"
|
|
272
271
|
| "reconnecting_newchannel_connected"
|
|
273
272
|
| "disconnecting";
|
|
@@ -389,9 +388,9 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
389
388
|
|
|
390
389
|
protected _setInternalState(internalState: InternalClientState): void {
|
|
391
390
|
const previousState = this._internalState;
|
|
392
|
-
if (doDebug) {
|
|
393
|
-
debugLog(
|
|
394
|
-
chalk.cyan(` Client ${this._instanceNumber} ${this.clientName} from `),
|
|
391
|
+
if (doDebug || traceInternalState) {
|
|
392
|
+
(traceInternalState ? warningLog : debugLog)(
|
|
393
|
+
chalk.cyan(` Client ${this._instanceNumber} ${this.clientName} : _internalState from `),
|
|
395
394
|
chalk.yellow(previousState),
|
|
396
395
|
"to",
|
|
397
396
|
chalk.yellow(internalState)
|
|
@@ -476,12 +475,17 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
476
475
|
|
|
477
476
|
private _cancel_reconnection(callback: ErrorCallback) {
|
|
478
477
|
// _cancel_reconnection is invoked during disconnection
|
|
479
|
-
// when we detect that a reconnection is in progress
|
|
478
|
+
// when we detect that a reconnection is in progress...
|
|
479
|
+
|
|
480
|
+
// istanbul ignore next
|
|
480
481
|
if (!this.isReconnecting) {
|
|
481
|
-
warningLog("internal error
|
|
482
|
+
warningLog("internal error: _cancel_reconnection should only be used when reconnecting is in progress");
|
|
482
483
|
}
|
|
484
|
+
|
|
483
485
|
debugLog("canceling reconnection");
|
|
486
|
+
|
|
484
487
|
this._reconnectionIsCanceled = true;
|
|
488
|
+
|
|
485
489
|
// istanbul ignore next
|
|
486
490
|
if (!this._secureChannel) {
|
|
487
491
|
debugLog("_cancel_reconnection: Nothing to do !");
|
|
@@ -502,7 +506,7 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
502
506
|
|
|
503
507
|
if (!this.knowsServerEndpoint) {
|
|
504
508
|
debugLog("Cannot reconnect , server endpoint is unknown");
|
|
505
|
-
return callback(new Error("Cannot reconnect, server endpoint is unknown"));
|
|
509
|
+
return callback(new Error("Cannot reconnect, server endpoint is unknown - this.knowsServerEndpoint = false"));
|
|
506
510
|
}
|
|
507
511
|
assert(this.knowsServerEndpoint);
|
|
508
512
|
|
|
@@ -521,7 +525,7 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
521
525
|
};
|
|
522
526
|
|
|
523
527
|
const _when_reconnectionIsCanceled = (callback: ErrorCallback) => {
|
|
524
|
-
warningLog("attempt to recreate a new secure channel : suspended
|
|
528
|
+
warningLog("attempt to recreate a new secure channel : suspended because reconnection is canceled !");
|
|
525
529
|
this.emit("reconnection_canceled");
|
|
526
530
|
return callback(new Error("Reconnection has been canceled - " + this.clientName));
|
|
527
531
|
};
|
|
@@ -573,7 +577,7 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
573
577
|
|
|
574
578
|
if (
|
|
575
579
|
err!.message.match("BadCertificateInvalid") ||
|
|
576
|
-
err!.message.match(/
|
|
580
|
+
err!.message.match(/socket has been disconnected by third party/)
|
|
577
581
|
) {
|
|
578
582
|
warningLog(
|
|
579
583
|
"the server certificate has changed, we need to retrieve server certificate again: ",
|
|
@@ -695,7 +699,7 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
695
699
|
],
|
|
696
700
|
(err) => {
|
|
697
701
|
if (err) {
|
|
698
|
-
|
|
702
|
+
errorLog("Inner create secure channel has failed", err.message);
|
|
699
703
|
if (this._secureChannel) {
|
|
700
704
|
this._secureChannel!.abortConnection(() => {
|
|
701
705
|
this._destroy_secure_channel();
|
|
@@ -839,7 +843,7 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
839
843
|
|
|
840
844
|
// istanbul ignore next
|
|
841
845
|
if (this._internalState !== "disconnected") {
|
|
842
|
-
callback(new Error(
|
|
846
|
+
callback(new Error(`client#connect failed, as invalid internal state = ${this._internalState}`));
|
|
843
847
|
return;
|
|
844
848
|
}
|
|
845
849
|
|
|
@@ -941,6 +945,16 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
941
945
|
return this._secureChannel ? this._secureChannel.getClientNonce() : null;
|
|
942
946
|
}
|
|
943
947
|
|
|
948
|
+
public requestReconnection() {
|
|
949
|
+
if (this._secureChannel) {
|
|
950
|
+
this._secureChannel.abortConnection(() => {
|
|
951
|
+
errorLog("new connection requested");
|
|
952
|
+
/*
|
|
953
|
+
*/
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
944
958
|
public performMessageTransaction(request: Request, callback: ResponseCallback<Response>): void {
|
|
945
959
|
if (!this._secureChannel) {
|
|
946
960
|
// this may happen if the Server has closed the connection abruptly for some unknown reason
|
|
@@ -960,7 +974,7 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
960
974
|
"performMessageTransaction: Invalid client state " +
|
|
961
975
|
this._internalState +
|
|
962
976
|
" while performing a transaction " +
|
|
963
|
-
request.
|
|
977
|
+
request.schema.name
|
|
964
978
|
)
|
|
965
979
|
);
|
|
966
980
|
}
|
|
@@ -1035,10 +1049,10 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
1035
1049
|
});
|
|
1036
1050
|
|
|
1037
1051
|
this.performMessageTransaction(request, (err: Error | null, response?: Response) => {
|
|
1038
|
-
this._serverEndpoints = [];
|
|
1039
1052
|
if (err) {
|
|
1040
1053
|
return callback(err);
|
|
1041
1054
|
}
|
|
1055
|
+
this._serverEndpoints = [];
|
|
1042
1056
|
// istanbul ignore next
|
|
1043
1057
|
if (!response || !(response instanceof GetEndpointsResponse)) {
|
|
1044
1058
|
return callback(new Error("Internal Error"));
|
|
@@ -1065,13 +1079,6 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
1065
1079
|
public findServers(options: FindServersRequestLike, callback: ResponseCallback<ApplicationDescription[]>): void;
|
|
1066
1080
|
public findServers(callback: ResponseCallback<ApplicationDescription[]>): void;
|
|
1067
1081
|
public findServers(...args: any[]): any {
|
|
1068
|
-
if (!this._secureChannel) {
|
|
1069
|
-
setImmediate(() => {
|
|
1070
|
-
callback(new Error("Invalid Secure Channel"));
|
|
1071
|
-
});
|
|
1072
|
-
return;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
1082
|
if (args.length === 1) {
|
|
1076
1083
|
return this.findServers({}, args[0]);
|
|
1077
1084
|
}
|
|
@@ -1107,14 +1114,6 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
1107
1114
|
}
|
|
1108
1115
|
const options = args[0] as FindServersOnNetworkRequestOptions;
|
|
1109
1116
|
const callback = args[1] as ResponseCallback<ServerOnNetwork[]>;
|
|
1110
|
-
|
|
1111
|
-
if (!this._secureChannel) {
|
|
1112
|
-
setImmediate(() => {
|
|
1113
|
-
callback(new Error("Invalid Secure Channel"));
|
|
1114
|
-
});
|
|
1115
|
-
return;
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
1117
|
const request = new FindServersOnNetworkRequest(options);
|
|
1119
1118
|
|
|
1120
1119
|
this.performMessageTransaction(request, (err: Error | null, response?: Response) => {
|
|
@@ -1325,6 +1324,10 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
1325
1324
|
str += " applicationName............... " + this.applicationName + "\n";
|
|
1326
1325
|
str += " applicationUri................ " + this._getBuiltApplicationUri() + "\n";
|
|
1327
1326
|
str += " clientName.................... " + this.clientName + "\n";
|
|
1327
|
+
str += " reconnectOnFailure............ " + this.reconnectOnFailure + "\n";
|
|
1328
|
+
str += " isReconnecting................ " + this.isReconnecting + "\n";
|
|
1329
|
+
str += " (internal state).............. " + this._internalState + "\n";
|
|
1330
|
+
str += " sessions count................ " + this.getSessions().length + "\n";
|
|
1328
1331
|
|
|
1329
1332
|
if (this._secureChannel) {
|
|
1330
1333
|
str += "secureChannel:\n" + this._secureChannel.toString();
|
|
@@ -1432,19 +1435,11 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
1432
1435
|
this._transactionsPerformed += this._secureChannel.transactionsPerformed;
|
|
1433
1436
|
this._timedOutRequestCount += this._secureChannel.timedOutRequestCount;
|
|
1434
1437
|
if (doDebug) {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
);
|
|
1439
|
-
debugLog(chalk.cyan(
|
|
1440
|
-
debugLog(
|
|
1441
|
-
chalk.cyan(` Client ${this._instanceNumber} ${this.clientName} transactions = `),
|
|
1442
|
-
this._transactionsPerformed
|
|
1443
|
-
);
|
|
1444
|
-
debugLog(
|
|
1445
|
-
chalk.cyan(` Client ${this._instanceNumber} ${this.clientName} timedOutRequestCount = `),
|
|
1446
|
-
this._timedOutRequestCount
|
|
1447
|
-
);
|
|
1438
|
+
const h = `Client ${this._instanceNumber} ${this.clientName}`;
|
|
1439
|
+
debugLog(chalk.cyan(`${h} byteWritten = `), this._byteWritten);
|
|
1440
|
+
debugLog(chalk.cyan(`${h} byteRead = `), this._byteRead);
|
|
1441
|
+
debugLog(chalk.cyan(`${h} transactions = `), this._transactionsPerformed);
|
|
1442
|
+
debugLog(chalk.cyan(`${h} timedOutRequestCount = `), this._timedOutRequestCount);
|
|
1448
1443
|
}
|
|
1449
1444
|
}
|
|
1450
1445
|
}
|
|
@@ -1563,6 +1558,9 @@ export class ClientBaseImpl extends OPCUASecureObject implements OPCUAClientBase
|
|
|
1563
1558
|
});
|
|
1564
1559
|
|
|
1565
1560
|
secureChannel.on("close", (err?: Error | null) => {
|
|
1561
|
+
if (err) {
|
|
1562
|
+
this._setInternalState("panic");
|
|
1563
|
+
}
|
|
1566
1564
|
debugLog(chalk.yellow.bold(" ClientBaseImpl emitting close"), err?.message);
|
|
1567
1565
|
this._destroy_secure_channel();
|
|
1568
1566
|
if (!err || !this.reconnectOnFailure) {
|
|
@@ -1687,7 +1685,7 @@ class TmpClient extends ClientBaseImpl {
|
|
|
1687
1685
|
|
|
1688
1686
|
// istanbul ignore next
|
|
1689
1687
|
if (this._internalState !== "disconnected") {
|
|
1690
|
-
callback!(new Error("TmpClient#connect: invalid internal state " + this._internalState));
|
|
1688
|
+
callback!(new Error("TmpClient#connect: invalid internal state = " + this._internalState));
|
|
1691
1689
|
return;
|
|
1692
1690
|
}
|
|
1693
1691
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @module node-opcua-client-private
|
|
3
3
|
*/
|
|
4
4
|
import { EventEmitter } from "events";
|
|
5
|
+
import { callbackify } from "util";
|
|
5
6
|
import * as chalk from "chalk";
|
|
6
7
|
import { assert } from "node-opcua-assert";
|
|
7
8
|
import { AggregateFunction } from "node-opcua-constants";
|
|
@@ -293,7 +294,6 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
|
|
|
293
294
|
this.timeout = 0;
|
|
294
295
|
}
|
|
295
296
|
|
|
296
|
-
|
|
297
297
|
getTransportSettings(): IBasicTransportSettings {
|
|
298
298
|
return this._client!.getTransportSettings();
|
|
299
299
|
}
|
|
@@ -1556,19 +1556,27 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
|
|
|
1556
1556
|
return this._client !== null && this._client._secureChannel !== null && this._client._secureChannel.isOpened();
|
|
1557
1557
|
}
|
|
1558
1558
|
|
|
1559
|
+
private requestReconnection() {
|
|
1560
|
+
if (this._client) {
|
|
1561
|
+
this._client.requestReconnection();
|
|
1562
|
+
assert(this._client.isReconnecting === true, "expecting client to be reconnecting now");
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1559
1566
|
public performMessageTransaction(request: Request, callback: (err: Error | null, response?: Response) => void): void {
|
|
1560
1567
|
if (!this._client) {
|
|
1561
1568
|
// session may have been closed by user ... but is still in used !!
|
|
1562
1569
|
return callback(new Error("Session has been closed and should not be used to perform a transaction anymore"));
|
|
1563
1570
|
}
|
|
1564
1571
|
|
|
1565
|
-
if (!this.isChannelValid()) {
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
+
// if (!this.isChannelValid()) {
|
|
1573
|
+
// // the secure channel is broken, may be the server has crashed or the network cable has been disconnected
|
|
1574
|
+
// // for a long time
|
|
1575
|
+
// // we may need to queue this transaction, as a secure token may be being reprocessed
|
|
1576
|
+
// errorLog(chalk.bgWhite.red("!!! Performing transaction on invalid channel !!! ", request.schema.name));
|
|
1577
|
+
// // this.requestReconnection();
|
|
1578
|
+
// return callback(new Error("!!! Performing transaction on invalid channel with " + request.schema.name + ": starting reconnection process"));
|
|
1579
|
+
// }
|
|
1572
1580
|
|
|
1573
1581
|
this._reconnecting.pendingTransactions = this._reconnecting.pendingTransactions || [];
|
|
1574
1582
|
this._reconnecting.pendingTransactionsCount = this._reconnecting.pendingTransactionsCount || 0;
|
|
@@ -2014,7 +2022,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
|
|
|
2014
2022
|
});
|
|
2015
2023
|
this._keepAliveManager.start();
|
|
2016
2024
|
}
|
|
2017
|
-
|
|
2025
|
+
|
|
2018
2026
|
public stopKeepAliveManager(): void {
|
|
2019
2027
|
if (this._keepAliveManager) {
|
|
2020
2028
|
this._keepAliveManager.stop();
|
|
@@ -2300,19 +2308,18 @@ async function promoteOpaqueStructure2(session: IBasicSession, callMethodResult:
|
|
|
2300
2308
|
function countOpaqueStructures(callMethodResults: CallMethodResult[]): number {
|
|
2301
2309
|
const x = (a: Variant[] | null): PseudoDataValue[] => {
|
|
2302
2310
|
if (a === null) return [] as PseudoDataValue[];
|
|
2303
|
-
return a.map((value) => {
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2311
|
+
return a.map((value) => {
|
|
2312
|
+
return { value: value };
|
|
2313
|
+
});
|
|
2314
|
+
};
|
|
2315
|
+
const opaqueStructureCount = callMethodResults.reduce((prev, callMethodResult) => {
|
|
2316
|
+
return prev + extractDataValueToPromote(x(callMethodResult.outputArguments)).length;
|
|
2317
|
+
}, 0);
|
|
2309
2318
|
return opaqueStructureCount;
|
|
2310
2319
|
}
|
|
2311
2320
|
async function promoteOpaqueStructure3(session: IBasicSession, callMethodResults: CallMethodResult[]): Promise<void> {
|
|
2312
|
-
|
|
2313
2321
|
const opaqueStructureCount = countOpaqueStructures(callMethodResults);
|
|
2314
|
-
if (0 === opaqueStructureCount)
|
|
2315
|
-
return;
|
|
2322
|
+
if (0 === opaqueStructureCount) return;
|
|
2316
2323
|
|
|
2317
2324
|
// construct dataTypeManager if not already present
|
|
2318
2325
|
await getExtraDataTypeManager(session);
|
|
@@ -2324,11 +2331,11 @@ async function promoteOpaqueStructure3(session: IBasicSession, callMethodResults
|
|
|
2324
2331
|
// tslint:disable:no-var-requires
|
|
2325
2332
|
// tslint:disable:max-line-length
|
|
2326
2333
|
const thenify = require("thenify");
|
|
2327
|
-
const callbackify = require("callbackify");
|
|
2328
2334
|
const opts = { multiArgs: false };
|
|
2329
2335
|
|
|
2330
2336
|
const promoteOpaqueStructureWithCallback = callbackify(promoteOpaqueStructure);
|
|
2331
2337
|
const promoteOpaqueStructure3WithCallback = callbackify(promoteOpaqueStructure3) as promoteOpaqueStructure3WithCallbackFunc;
|
|
2338
|
+
// ClientSessionImpl.prototype.constructExtensionObject = callbackify(ClientSessionImpl.prototype.constructExtensionObject) as any;
|
|
2332
2339
|
|
|
2333
2340
|
ClientSessionImpl.prototype.browse = thenify.withCallback(ClientSessionImpl.prototype.browse, opts);
|
|
2334
2341
|
ClientSessionImpl.prototype.browseNext = thenify.withCallback(ClientSessionImpl.prototype.browseNext, opts);
|
|
@@ -2367,5 +2374,4 @@ ClientSessionImpl.prototype.registerNodes = thenify.withCallback(ClientSessionIm
|
|
|
2367
2374
|
ClientSessionImpl.prototype.unregisterNodes = thenify.withCallback(ClientSessionImpl.prototype.unregisterNodes, opts);
|
|
2368
2375
|
ClientSessionImpl.prototype.readNamespaceArray = thenify.withCallback(ClientSessionImpl.prototype.readNamespaceArray, opts);
|
|
2369
2376
|
ClientSessionImpl.prototype.getBuiltInDataType = thenify.withCallback(ClientSessionImpl.prototype.getBuiltInDataType, opts);
|
|
2370
|
-
ClientSessionImpl.prototype.constructExtensionObject = callbackify(ClientSessionImpl.prototype.constructExtensionObject);
|
|
2371
2377
|
ClientSessionImpl.prototype.changeUser = thenify.withCallback(ClientSessionImpl.prototype.changeUser, opts);
|
|
@@ -755,10 +755,10 @@ export class OPCUAClientImpl extends ClientBaseImpl implements OPCUAClient {
|
|
|
755
755
|
}
|
|
756
756
|
// istanbul ignore next
|
|
757
757
|
if (!this.__resolveEndPoint() || !this.endpoint) {
|
|
758
|
-
return callback!(
|
|
758
|
+
return callback!(
|
|
759
759
|
new Error(
|
|
760
|
-
" End point must exist " + this._secureChannel!.endpointUrl +
|
|
761
|
-
" securityMode = " + MessageSecurityMode[this.securityMode] +
|
|
760
|
+
" End point must exist " + this._secureChannel!.endpointUrl +
|
|
761
|
+
" securityMode = " + MessageSecurityMode[this.securityMode] +
|
|
762
762
|
" securityPolicy = " + this.securityPolicy));
|
|
763
763
|
}
|
|
764
764
|
|
|
@@ -805,10 +805,7 @@ export class OPCUAClientImpl extends ClientBaseImpl implements OPCUAClient {
|
|
|
805
805
|
* @private
|
|
806
806
|
*/
|
|
807
807
|
public _on_connection_reestablished(callback: (err?: Error) => void): void {
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
// call base class implementation first
|
|
811
|
-
ClientBaseImpl.prototype._on_connection_reestablished.call(this, (/*err?: Error*/) => {
|
|
808
|
+
super._on_connection_reestablished((/*err?: Error*/) => {
|
|
812
809
|
repair_client_sessions(this, callback);
|
|
813
810
|
});
|
|
814
811
|
}
|
|
@@ -849,7 +846,7 @@ export class OPCUAClientImpl extends ClientBaseImpl implements OPCUAClient {
|
|
|
849
846
|
this.clientNonce = crypto.randomBytes(32);
|
|
850
847
|
|
|
851
848
|
// recycle session name if already exists
|
|
852
|
-
const sessionName =
|
|
849
|
+
const sessionName = session.name
|
|
853
850
|
|
|
854
851
|
const request = new CreateSessionRequest({
|
|
855
852
|
clientCertificate: this.getCertificate(),
|
|
@@ -1163,15 +1160,15 @@ export class OPCUAClientImpl extends ClientBaseImpl implements OPCUAClient {
|
|
|
1163
1160
|
this._serverEndpoints.map(
|
|
1164
1161
|
(endpoint) =>
|
|
1165
1162
|
endpoint.endpointUrl + " "
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1163
|
+
+ MessageSecurityMode[endpoint.securityMode] + " "
|
|
1164
|
+
+ endpoint.securityPolicyUri + " "
|
|
1165
|
+
+ endpoint.userIdentityTokens?.map((u) => UserTokenType[u.tokenType]).join(",")
|
|
1169
1166
|
).join('\n')
|
|
1170
1167
|
);
|
|
1171
1168
|
}
|
|
1172
1169
|
return callback(new Error(
|
|
1173
|
-
" End point must exist " + this._secureChannel!.endpointUrl +
|
|
1174
|
-
" securityMode = " + MessageSecurityMode[this.securityMode] +
|
|
1170
|
+
" End point must exist " + this._secureChannel!.endpointUrl +
|
|
1171
|
+
" securityMode = " + MessageSecurityMode[this.securityMode] +
|
|
1175
1172
|
" securityPolicy = " + this.securityPolicy));
|
|
1176
1173
|
}
|
|
1177
1174
|
this.serverUri = this.endpoint.server.applicationUri || "invalid application uri";
|
package/source/reconnection.ts
CHANGED
|
@@ -139,7 +139,7 @@ function create_session_and_repeat_if_failed(
|
|
|
139
139
|
callback: CallbackT<ClientSessionImpl>
|
|
140
140
|
) {
|
|
141
141
|
if (session.hasBeenClosed()) {
|
|
142
|
-
doDebug && debugLog("Cannot complete subscription republish due to session
|
|
142
|
+
doDebug && debugLog("Cannot complete subscription republish due to session termination");
|
|
143
143
|
return callback(new Error("Cannot complete subscription republish due to session termination"));
|
|
144
144
|
}
|
|
145
145
|
doDebug && debugLog(chalk.bgWhite.red(" => creating a new session ...."));
|
|
@@ -147,7 +147,7 @@ function create_session_and_repeat_if_failed(
|
|
|
147
147
|
// so we can reuse subscriptions data
|
|
148
148
|
client.__createSession_step2(session, (err: Error | null, session1?: ClientSessionImpl) => {
|
|
149
149
|
if (err && session.hasBeenClosed()) {
|
|
150
|
-
doDebug && debugLog("Cannot complete subscription republish due to session
|
|
150
|
+
doDebug && debugLog("Cannot complete subscription republish due to session termination");
|
|
151
151
|
return callback(new Error("Cannot complete subscription republish due to session termination"));
|
|
152
152
|
}
|
|
153
153
|
if (!err && session1) {
|
|
@@ -433,9 +433,14 @@ export function repair_client_session(client: IClientBase, session: ClientSessio
|
|
|
433
433
|
session.sessionId.toString(),
|
|
434
434
|
" => Let's retry"
|
|
435
435
|
);
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
436
|
+
if (!session.hasBeenClosed()) {
|
|
437
|
+
setTimeout(() => {
|
|
438
|
+
_repair_client_session(client, session, callback);
|
|
439
|
+
}, 2000);
|
|
440
|
+
} else {
|
|
441
|
+
// session does not need to be repaired anymore
|
|
442
|
+
callback();
|
|
443
|
+
}
|
|
439
444
|
return;
|
|
440
445
|
}
|
|
441
446
|
doDebug && debugLog(chalk.yellow("session has been restored"), session.sessionId.toString());
|
|
@@ -452,9 +457,8 @@ export function repair_client_session(client: IClientBase, session: ClientSessio
|
|
|
452
457
|
}
|
|
453
458
|
|
|
454
459
|
export function repair_client_sessions(client: IClientBase, callback: (err?: Error) => void): void {
|
|
455
|
-
const self = client;
|
|
456
460
|
// repair session
|
|
457
|
-
const sessions =
|
|
461
|
+
const sessions = client.getSessions();
|
|
458
462
|
doDebug && debugLog(chalk.red.bgWhite(" Starting sessions reactivation", sessions.length));
|
|
459
463
|
async.map(
|
|
460
464
|
sessions,
|