node-opcua-server 2.72.2 → 2.74.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/LICENSE +3 -1
- package/dist/helper.d.ts +10 -0
- package/dist/helper.js +76 -0
- package/dist/helper.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/monitored_item.js +2 -1
- package/dist/monitored_item.js.map +1 -1
- package/dist/opcua_server.js +26 -22
- package/dist/opcua_server.js.map +1 -1
- package/dist/server_capabilities.js +5 -4
- package/dist/server_capabilities.js.map +1 -1
- package/dist/server_engine.d.ts +1 -1
- package/dist/server_engine.js +25 -25
- package/dist/server_engine.js.map +1 -1
- package/dist/server_publish_engine.d.ts +6 -5
- package/dist/server_publish_engine.js +22 -11
- package/dist/server_publish_engine.js.map +1 -1
- package/dist/server_publish_engine_for_orphan_subscriptions.js +3 -1
- package/dist/server_publish_engine_for_orphan_subscriptions.js.map +1 -1
- package/dist/server_session.d.ts +4 -3
- package/dist/server_session.js +7 -6
- package/dist/server_session.js.map +1 -1
- package/dist/server_subscription.d.ts +8 -2
- package/dist/server_subscription.js +75 -62
- package/dist/server_subscription.js.map +1 -1
- package/dist/sessions_compatible_for_transfer.d.ts +1 -1
- package/dist/sessions_compatible_for_transfer.js +3 -0
- package/dist/sessions_compatible_for_transfer.js.map +1 -1
- package/package.json +48 -47
- package/source/helper.ts +87 -0
- package/source/index.ts +2 -1
- package/source/monitored_item.ts +3 -2
- package/source/opcua_server.ts +27 -26
- package/source/server_capabilities.ts +5 -4
- package/source/server_engine.ts +29 -27
- package/source/server_publish_engine.ts +34 -21
- package/source/server_publish_engine_for_orphan_subscriptions.ts +6 -1
- package/source/server_session.ts +15 -13
- package/source/server_subscription.ts +89 -72
- package/source/sessions_compatible_for_transfer.ts +5 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ServerSession } from "./server_session";
|
|
2
|
-
export declare function sessionsCompatibleForTransfer(sessionSrc: ServerSession, sessionDest: ServerSession): boolean;
|
|
2
|
+
export declare function sessionsCompatibleForTransfer(sessionSrc: ServerSession | undefined, sessionDest: ServerSession): boolean;
|
|
@@ -4,6 +4,9 @@ exports.sessionsCompatibleForTransfer = void 0;
|
|
|
4
4
|
const node_opcua_assert_1 = require("node-opcua-assert");
|
|
5
5
|
const node_opcua_types_1 = require("node-opcua-types");
|
|
6
6
|
function sessionsCompatibleForTransfer(sessionSrc, sessionDest) {
|
|
7
|
+
if (!sessionSrc) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
7
10
|
(0, node_opcua_assert_1.assert)(sessionDest);
|
|
8
11
|
(0, node_opcua_assert_1.assert)(sessionSrc);
|
|
9
12
|
if (!sessionSrc.userIdentityToken && !sessionDest.userIdentityToken) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions_compatible_for_transfer.js","sourceRoot":"","sources":["../source/sessions_compatible_for_transfer.ts"],"names":[],"mappings":";;;AAAA,yDAA2C;AAC3C,uDAAuH;AAGvH,SAAgB,6BAA6B,CAAC,
|
|
1
|
+
{"version":3,"file":"sessions_compatible_for_transfer.js","sourceRoot":"","sources":["../source/sessions_compatible_for_transfer.ts"],"names":[],"mappings":";;;AAAA,yDAA2C;AAC3C,uDAAuH;AAGvH,SAAgB,6BAA6B,CAAC,UAAqC,EAAE,WAA0B;IAE3G,IAAI,CAAC,UAAU,EAAE;QACb,OAAO,IAAI,CAAC;KACf;IACD,IAAA,0BAAM,EAAC,WAAW,CAAC,CAAC;IACpB,IAAA,0BAAM,EAAC,UAAU,CAAC,CAAC;IACnB,IAAI,CAAC,UAAU,CAAC,iBAAiB,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE;QACjE,OAAO,IAAI,CAAC;KACf;IACD,IAAI,UAAU,CAAC,iBAAiB,YAAY,yCAAsB,EAAE;QAChE,IAAI,CAAC,CAAC,WAAW,CAAC,iBAAiB,YAAY,yCAAsB,CAAC,EAAE;YACpE,OAAO,KAAK,CAAC;SAChB;QACD,OAAO,IAAI,CAAC;KACf;SAAM,IAAI,UAAU,CAAC,iBAAiB,YAAY,wCAAqB,EAAE;QACtE,IAAI,CAAC,CAAC,WAAW,CAAC,iBAAiB,YAAY,wCAAqB,CAAC,EAAE;YACnE,OAAO,KAAK,CAAC;SAChB;QACD,OAAO,UAAU,CAAC,iBAAiB,CAAC,QAAQ,KAAK,WAAW,CAAC,iBAAiB,CAAC,QAAQ,CAAC;KAC3F;IACD,uBAAuB;SAClB,IAAI,UAAU,CAAC,iBAAiB,YAAY,oCAAiB,EAAE;QAChE,IAAI,CAAC,CAAC,WAAW,CAAC,iBAAiB,YAAY,oCAAiB,CAAC,EAAE;YAC/D,OAAO,KAAK,CAAC;SAChB;QACD,OAAO,CACH,UAAU,CAAC,iBAAiB,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC5D,WAAW,CAAC,iBAAiB,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAChE,CAAC;KACL;SAAM;QACH,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;KACjD;AACL,CAAC;AAjCD,sEAiCC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-opcua-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.74.0",
|
|
4
4
|
"description": "pure nodejs OPCUA SDK - module -server",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsc -b",
|
|
@@ -17,55 +17,56 @@
|
|
|
17
17
|
"async": "^3.2.4",
|
|
18
18
|
"dequeue": "^1.0.5",
|
|
19
19
|
"lodash": "4.17.21",
|
|
20
|
-
"node-opcua-address-space": "2.
|
|
21
|
-
"node-opcua-assert": "2.
|
|
22
|
-
"node-opcua-basic-types": "2.
|
|
23
|
-
"node-opcua-
|
|
24
|
-
"node-opcua-
|
|
25
|
-
"node-opcua-client
|
|
26
|
-
"node-opcua-
|
|
27
|
-
"node-opcua-
|
|
20
|
+
"node-opcua-address-space": "2.74.0",
|
|
21
|
+
"node-opcua-assert": "2.74.0",
|
|
22
|
+
"node-opcua-basic-types": "2.74.0",
|
|
23
|
+
"node-opcua-binary-stream": "2.74.0",
|
|
24
|
+
"node-opcua-certificate-manager": "2.74.0",
|
|
25
|
+
"node-opcua-client": "2.74.0",
|
|
26
|
+
"node-opcua-client-dynamic-extension-object": "2.74.0",
|
|
27
|
+
"node-opcua-common": "2.74.0",
|
|
28
|
+
"node-opcua-constants": "2.74.0",
|
|
28
29
|
"node-opcua-crypto": "^1.11.0",
|
|
29
|
-
"node-opcua-data-access": "2.
|
|
30
|
-
"node-opcua-data-model": "2.
|
|
31
|
-
"node-opcua-data-value": "2.
|
|
32
|
-
"node-opcua-date-time": "2.
|
|
33
|
-
"node-opcua-debug": "2.
|
|
34
|
-
"node-opcua-enum": "2.
|
|
35
|
-
"node-opcua-extension-object": "2.
|
|
36
|
-
"node-opcua-factory": "2.
|
|
37
|
-
"node-opcua-hostname": "2.
|
|
38
|
-
"node-opcua-nodeid": "2.
|
|
39
|
-
"node-opcua-nodeset-ua": "2.
|
|
40
|
-
"node-opcua-nodesets": "2.
|
|
41
|
-
"node-opcua-numeric-range": "2.
|
|
42
|
-
"node-opcua-object-registry": "2.
|
|
30
|
+
"node-opcua-data-access": "2.74.0",
|
|
31
|
+
"node-opcua-data-model": "2.74.0",
|
|
32
|
+
"node-opcua-data-value": "2.74.0",
|
|
33
|
+
"node-opcua-date-time": "2.74.0",
|
|
34
|
+
"node-opcua-debug": "2.74.0",
|
|
35
|
+
"node-opcua-enum": "2.74.0",
|
|
36
|
+
"node-opcua-extension-object": "2.74.0",
|
|
37
|
+
"node-opcua-factory": "2.74.0",
|
|
38
|
+
"node-opcua-hostname": "2.74.0",
|
|
39
|
+
"node-opcua-nodeid": "2.74.0",
|
|
40
|
+
"node-opcua-nodeset-ua": "2.74.0",
|
|
41
|
+
"node-opcua-nodesets": "2.74.0",
|
|
42
|
+
"node-opcua-numeric-range": "2.74.0",
|
|
43
|
+
"node-opcua-object-registry": "2.74.0",
|
|
43
44
|
"node-opcua-pki": "^2.17.0",
|
|
44
|
-
"node-opcua-secure-channel": "2.
|
|
45
|
-
"node-opcua-service-browse": "2.
|
|
46
|
-
"node-opcua-service-call": "2.
|
|
47
|
-
"node-opcua-service-discovery": "2.
|
|
48
|
-
"node-opcua-service-endpoints": "2.
|
|
49
|
-
"node-opcua-service-filter": "2.
|
|
50
|
-
"node-opcua-service-history": "2.
|
|
51
|
-
"node-opcua-service-node-management": "2.
|
|
52
|
-
"node-opcua-service-query": "2.
|
|
53
|
-
"node-opcua-service-read": "2.
|
|
54
|
-
"node-opcua-service-register-node": "2.
|
|
55
|
-
"node-opcua-service-secure-channel": "2.
|
|
56
|
-
"node-opcua-service-session": "2.
|
|
57
|
-
"node-opcua-service-subscription": "2.
|
|
58
|
-
"node-opcua-service-translate-browse-path": "2.
|
|
59
|
-
"node-opcua-service-write": "2.
|
|
60
|
-
"node-opcua-status-code": "2.
|
|
61
|
-
"node-opcua-transport": "2.
|
|
62
|
-
"node-opcua-types": "2.
|
|
63
|
-
"node-opcua-utils": "2.
|
|
64
|
-
"node-opcua-variant": "2.
|
|
45
|
+
"node-opcua-secure-channel": "2.74.0",
|
|
46
|
+
"node-opcua-service-browse": "2.74.0",
|
|
47
|
+
"node-opcua-service-call": "2.74.0",
|
|
48
|
+
"node-opcua-service-discovery": "2.74.0",
|
|
49
|
+
"node-opcua-service-endpoints": "2.74.0",
|
|
50
|
+
"node-opcua-service-filter": "2.74.0",
|
|
51
|
+
"node-opcua-service-history": "2.74.0",
|
|
52
|
+
"node-opcua-service-node-management": "2.74.0",
|
|
53
|
+
"node-opcua-service-query": "2.74.0",
|
|
54
|
+
"node-opcua-service-read": "2.74.0",
|
|
55
|
+
"node-opcua-service-register-node": "2.74.0",
|
|
56
|
+
"node-opcua-service-secure-channel": "2.74.0",
|
|
57
|
+
"node-opcua-service-session": "2.74.0",
|
|
58
|
+
"node-opcua-service-subscription": "2.74.0",
|
|
59
|
+
"node-opcua-service-translate-browse-path": "2.74.0",
|
|
60
|
+
"node-opcua-service-write": "2.74.0",
|
|
61
|
+
"node-opcua-status-code": "2.74.0",
|
|
62
|
+
"node-opcua-transport": "2.74.0",
|
|
63
|
+
"node-opcua-types": "2.74.0",
|
|
64
|
+
"node-opcua-utils": "2.74.0",
|
|
65
|
+
"node-opcua-variant": "2.74.0"
|
|
65
66
|
},
|
|
66
67
|
"devDependencies": {
|
|
67
|
-
"node-opcua-leak-detector": "2.
|
|
68
|
-
"node-opcua-test-helpers": "2.
|
|
68
|
+
"node-opcua-leak-detector": "2.74.0",
|
|
69
|
+
"node-opcua-test-helpers": "2.74.0",
|
|
69
70
|
"should": "^13.2.3",
|
|
70
71
|
"sinon": "^14.0.0"
|
|
71
72
|
},
|
|
@@ -84,5 +85,5 @@
|
|
|
84
85
|
"internet of things"
|
|
85
86
|
],
|
|
86
87
|
"homepage": "http://node-opcua.github.io/",
|
|
87
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "003ee041795f3b737afaaef5721045ee31ea9f77"
|
|
88
89
|
}
|
package/source/helper.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as util from "util";
|
|
2
|
+
import { OPCUAServer } from "./opcua_server";
|
|
3
|
+
import { ServerEngine } from "./server_engine";
|
|
4
|
+
import { ServerSession } from "./server_session";
|
|
5
|
+
import { Subscription, SubscriptionState } from "./server_subscription";
|
|
6
|
+
|
|
7
|
+
const consolelog = (...args: any) => {
|
|
8
|
+
const d = new Date();
|
|
9
|
+
const t = d.toTimeString().split(" ")[0] + "." + d.getMilliseconds().toString().padStart(3, "0");
|
|
10
|
+
console.log.apply(console, [t, ...args]);
|
|
11
|
+
};
|
|
12
|
+
const doDebug = false;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
export function installSessionLogging(server: OPCUAServer) {
|
|
19
|
+
installSessionLoggingOnEngine(server.engine);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const info = (subscription: Subscription) => {
|
|
23
|
+
return util.format(
|
|
24
|
+
subscription.subscriptionId,
|
|
25
|
+
SubscriptionState[subscription.state].padEnd(9),
|
|
26
|
+
subscription.state,
|
|
27
|
+
"kac=",
|
|
28
|
+
subscription.currentKeepAliveCount.toString().padStart(3)+
|
|
29
|
+
"/"+
|
|
30
|
+
subscription.maxKeepAliveCount.toString().padStart(3),
|
|
31
|
+
"ltc=",
|
|
32
|
+
subscription.currentLifetimeCount.toString().padStart(3)+
|
|
33
|
+
"/"+
|
|
34
|
+
subscription.lifeTimeCount.toString().padStart(3),
|
|
35
|
+
"prc=",
|
|
36
|
+
subscription.publishEngine?.pendingPublishRequestCount.toString().padStart(3),
|
|
37
|
+
"pi=",
|
|
38
|
+
subscription.publishingInterval
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export function installSubscriptionMonitoring(subscription: Subscription) {
|
|
43
|
+
consolelog("new_subscription", subscription.subscriptionId, info(subscription));
|
|
44
|
+
subscription.on("lifeTimeExpired", () => {
|
|
45
|
+
consolelog("lifeTimeExpired".padEnd(45), info(subscription));
|
|
46
|
+
});
|
|
47
|
+
if (true || doDebug) {
|
|
48
|
+
subscription.on("lifeTimeCounterChanged", (ltc: number) => {
|
|
49
|
+
consolelog("subscription lifeTimeCounterChanged".padEnd(45), info(subscription));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
subscription.on("expired", () => {
|
|
53
|
+
consolelog("subscription expired".padEnd(45), info(subscription));
|
|
54
|
+
});
|
|
55
|
+
subscription.on("stateChanged", (state: SubscriptionState) => {
|
|
56
|
+
consolelog("subscription stateChanged".padEnd(45), info(subscription));
|
|
57
|
+
});
|
|
58
|
+
subscription.on("terminate", () => {
|
|
59
|
+
consolelog("subscription terminated".padEnd(45), info(subscription));
|
|
60
|
+
});
|
|
61
|
+
subscription.on("keepalive", () => {
|
|
62
|
+
consolelog("subscription keepalive".padEnd(45), info(subscription));
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export function installSessionLoggingOnEngine(serverEngine: ServerEngine) {
|
|
66
|
+
function on_create_session(session: ServerSession) {
|
|
67
|
+
try {
|
|
68
|
+
session.on("activate_session", function () {
|
|
69
|
+
consolelog("activate_session");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
session.on("statusChanged", (status) => {
|
|
73
|
+
consolelog("session status changed: ", status);
|
|
74
|
+
});
|
|
75
|
+
session.on("new_subscription", function (subscription) {
|
|
76
|
+
installSubscriptionMonitoring(subscription);
|
|
77
|
+
});
|
|
78
|
+
} catch (err) {
|
|
79
|
+
consolelog((err as any).message);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
serverEngine.on("create_session", on_create_session);
|
|
83
|
+
serverEngine.once("session_closed", function (session) {
|
|
84
|
+
consolelog("session is closed");
|
|
85
|
+
serverEngine.removeListener("create_session", on_create_session);
|
|
86
|
+
});
|
|
87
|
+
}
|
package/source/index.ts
CHANGED
package/source/monitored_item.ts
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
coerceTimestampsToReturn,
|
|
26
26
|
sameStatusCode
|
|
27
27
|
} from "node-opcua-data-value";
|
|
28
|
-
import { checkDebugFlag, make_debugLog } from "node-opcua-debug";
|
|
28
|
+
import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
|
|
29
29
|
import { ExtensionObject } from "node-opcua-extension-object";
|
|
30
30
|
import { NodeId } from "node-opcua-nodeid";
|
|
31
31
|
import { NumericalRange0, NumericRange } from "node-opcua-numeric-range";
|
|
@@ -71,6 +71,7 @@ const defaultItemToMonitor: ReadValueIdOptions = new ReadValueId({
|
|
|
71
71
|
|
|
72
72
|
const debugLog = make_debugLog(__filename);
|
|
73
73
|
const doDebug = checkDebugFlag(__filename);
|
|
74
|
+
const warningLog = make_warningLog(__filename);
|
|
74
75
|
|
|
75
76
|
function _adjust_sampling_interval(samplingInterval: number, node_minimumSamplingInterval: number): number {
|
|
76
77
|
assert(typeof node_minimumSamplingInterval === "number", "expecting a number");
|
|
@@ -216,7 +217,7 @@ function apply_dataChange_filter(this: MonitoredItem, newDataValue: DataValue, o
|
|
|
216
217
|
debugLog("timestampHasChanged ", timestampHasChanged(newDataValue.sourceTimestamp, oldDataValue.sourceTimestamp));
|
|
217
218
|
}
|
|
218
219
|
} catch (err) {
|
|
219
|
-
|
|
220
|
+
warningLog(err);
|
|
220
221
|
}
|
|
221
222
|
}
|
|
222
223
|
switch (trigger) {
|
package/source/opcua_server.ts
CHANGED
|
@@ -145,7 +145,8 @@ import {
|
|
|
145
145
|
BuildInfoOptions,
|
|
146
146
|
MonitoredItemCreateResult,
|
|
147
147
|
IssuedIdentityToken,
|
|
148
|
-
BrowseResultOptions
|
|
148
|
+
BrowseResultOptions,
|
|
149
|
+
ServiceFault
|
|
149
150
|
} from "node-opcua-types";
|
|
150
151
|
import { DataType } from "node-opcua-variant";
|
|
151
152
|
import { VariantArrayType } from "node-opcua-variant";
|
|
@@ -184,7 +185,7 @@ const warningLog = make_warningLog(__filename);
|
|
|
184
185
|
const default_maxConnectionsPerEndpoint = 10;
|
|
185
186
|
|
|
186
187
|
function g_sendError(channel: ServerSecureChannelLayer, message: Message, ResponseClass: any, statusCode: StatusCode): void {
|
|
187
|
-
const response = new
|
|
188
|
+
const response = new ServiceFault({
|
|
188
189
|
responseHeader: { serviceResult: statusCode }
|
|
189
190
|
});
|
|
190
191
|
return channel.send_response("MSG", response, message);
|
|
@@ -203,6 +204,7 @@ const default_build_info: BuildInfoOptions = {
|
|
|
203
204
|
const minSessionTimeout = 100; // 100 milliseconds
|
|
204
205
|
const defaultSessionTimeout = 1000 * 30; // 30 seconds
|
|
205
206
|
const maxSessionTimeout = 1000 * 60 * 50; // 50 minutes
|
|
207
|
+
let unnamed_session_count = 0;
|
|
206
208
|
|
|
207
209
|
type ResponseClassType =
|
|
208
210
|
| typeof BrowseResponse
|
|
@@ -252,7 +254,7 @@ function moveSessionToChannel(session: ServerSession, channel: ServerSecureChann
|
|
|
252
254
|
}
|
|
253
255
|
|
|
254
256
|
async function _attempt_to_close_some_old_unactivated_session(server: OPCUAServer) {
|
|
255
|
-
const session = server.engine!.
|
|
257
|
+
const session = server.engine!.getOldestInactiveSession();
|
|
256
258
|
if (session) {
|
|
257
259
|
await server.engine!.closeSession(session.authenticationToken, false, "Forcing");
|
|
258
260
|
}
|
|
@@ -1786,7 +1788,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
1786
1788
|
assert(session.sessionTimeout === revisedSessionTimeout);
|
|
1787
1789
|
|
|
1788
1790
|
session.clientDescription = request.clientDescription;
|
|
1789
|
-
session.sessionName = request.sessionName ||
|
|
1791
|
+
session.sessionName = request.sessionName || `<unknown session name ${unnamed_session_count++}>`;
|
|
1790
1792
|
|
|
1791
1793
|
// Depending upon on the SecurityPolicy and the SecurityMode of the SecureChannel, the exchange of
|
|
1792
1794
|
// ApplicationInstanceCertificates and Nonces may be optional and the signatures may be empty. See
|
|
@@ -2232,13 +2234,14 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
2232
2234
|
|
|
2233
2235
|
function sendResponse(response1: Response) {
|
|
2234
2236
|
try {
|
|
2235
|
-
assert(response1 instanceof ResponseClass);
|
|
2237
|
+
assert(response1 instanceof ResponseClass || response1 instanceof ServiceFault);
|
|
2236
2238
|
if (message.session) {
|
|
2237
2239
|
const counterName = ResponseClass.name.replace("Response", "");
|
|
2238
2240
|
message.session.incrementRequestTotalCounter(counterName);
|
|
2239
2241
|
}
|
|
2240
2242
|
return channel.send_response("MSG", response1, message);
|
|
2241
2243
|
} catch (err) {
|
|
2244
|
+
warningLog(err);
|
|
2242
2245
|
// istanbul ignore next
|
|
2243
2246
|
if (err instanceof Error) {
|
|
2244
2247
|
// istanbul ignore next
|
|
@@ -3069,7 +3072,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3069
3072
|
(session: ServerSession, sendResponse: (response: Response) => void, sendError: (statusCode: StatusCode) => void) => {
|
|
3070
3073
|
assert(session);
|
|
3071
3074
|
assert(session.publishEngine); // server.publishEngine doesn't exists, OPCUAServer has probably shut down already
|
|
3072
|
-
session.publishEngine._on_PublishRequest(request, (
|
|
3075
|
+
session.publishEngine._on_PublishRequest(request, (_request1, response) => {
|
|
3073
3076
|
sendResponse(response);
|
|
3074
3077
|
});
|
|
3075
3078
|
}
|
|
@@ -3136,7 +3139,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3136
3139
|
|
|
3137
3140
|
sendResponse(response);
|
|
3138
3141
|
} catch (err) {
|
|
3139
|
-
|
|
3142
|
+
warningLog(err);
|
|
3140
3143
|
return sendError(StatusCodes.BadInternalError);
|
|
3141
3144
|
}
|
|
3142
3145
|
}
|
|
@@ -3178,16 +3181,20 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3178
3181
|
linksToAdd,
|
|
3179
3182
|
linksToRemove
|
|
3180
3183
|
);
|
|
3181
|
-
|
|
3182
|
-
responseHeader: { serviceResult: statusCode }
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
removeDiagnosticInfos: null
|
|
3188
|
-
});
|
|
3184
|
+
if (statusCode !== StatusCodes.Good) {
|
|
3185
|
+
const response = new ServiceFault({ responseHeader: { serviceResult: statusCode } });
|
|
3186
|
+
sendResponse(response);
|
|
3187
|
+
} else {
|
|
3188
|
+
const response = new SetTriggeringResponse({
|
|
3189
|
+
responseHeader: { serviceResult: statusCode },
|
|
3189
3190
|
|
|
3190
|
-
|
|
3191
|
+
addResults,
|
|
3192
|
+
removeResults,
|
|
3193
|
+
addDiagnosticInfos: null,
|
|
3194
|
+
removeDiagnosticInfos: null
|
|
3195
|
+
});
|
|
3196
|
+
sendResponse(response);
|
|
3197
|
+
}
|
|
3191
3198
|
}
|
|
3192
3199
|
);
|
|
3193
3200
|
}
|
|
@@ -3388,11 +3395,8 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3388
3395
|
message,
|
|
3389
3396
|
channel,
|
|
3390
3397
|
(session: ServerSession, sendResponse: (response: Response) => void, sendError: (statusCode: StatusCode) => void) => {
|
|
3391
|
-
let response;
|
|
3392
|
-
|
|
3393
3398
|
if (!request.nodesToRegister || request.nodesToRegister.length === 0) {
|
|
3394
|
-
|
|
3395
|
-
return sendResponse(response);
|
|
3399
|
+
return sendError(StatusCodes.BadNothingToDo);
|
|
3396
3400
|
}
|
|
3397
3401
|
if (this.engine.serverCapabilities.operationLimits.maxNodesPerRegisterNodes > 0) {
|
|
3398
3402
|
if (request.nodesToRegister.length > this.engine.serverCapabilities.operationLimits.maxNodesPerRegisterNodes) {
|
|
@@ -3408,7 +3412,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3408
3412
|
// NodeId from the request.
|
|
3409
3413
|
const registeredNodeIds = request.nodesToRegister.map((nodeId) => session.registerNode(nodeId));
|
|
3410
3414
|
|
|
3411
|
-
response = new RegisterNodesResponse({
|
|
3415
|
+
const response = new RegisterNodesResponse({
|
|
3412
3416
|
registeredNodeIds
|
|
3413
3417
|
});
|
|
3414
3418
|
sendResponse(response);
|
|
@@ -3425,13 +3429,10 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3425
3429
|
message,
|
|
3426
3430
|
channel,
|
|
3427
3431
|
(session: ServerSession, sendResponse: (response: Response) => void, sendError: (statusCode: StatusCode) => void) => {
|
|
3428
|
-
let response;
|
|
3429
|
-
|
|
3430
3432
|
request.nodesToUnregister = request.nodesToUnregister || [];
|
|
3431
3433
|
|
|
3432
3434
|
if (!request.nodesToUnregister || request.nodesToUnregister.length === 0) {
|
|
3433
|
-
|
|
3434
|
-
return sendResponse(response);
|
|
3435
|
+
return sendError(StatusCodes.BadNothingToDo);
|
|
3435
3436
|
}
|
|
3436
3437
|
|
|
3437
3438
|
if (this.engine.serverCapabilities.operationLimits.maxNodesPerRegisterNodes > 0) {
|
|
@@ -3444,7 +3445,7 @@ export class OPCUAServer extends OPCUABaseServer {
|
|
|
3444
3445
|
|
|
3445
3446
|
request.nodesToUnregister.map((nodeId: NodeId) => session.unRegisterNode(nodeId));
|
|
3446
3447
|
|
|
3447
|
-
response = new UnregisterNodesResponse({});
|
|
3448
|
+
const response = new UnregisterNodesResponse({});
|
|
3448
3449
|
sendResponse(response);
|
|
3449
3450
|
}
|
|
3450
3451
|
);
|
|
@@ -154,9 +154,9 @@ export type ServerCapabilitiesOptions = Partial<IServerCapabilities>;
|
|
|
154
154
|
export const defaultServerCapabilities: IServerCapabilities = {
|
|
155
155
|
maxBrowseContinuationPoints: 0,
|
|
156
156
|
maxHistoryContinuationPoints: 0,
|
|
157
|
-
maxStringLength:
|
|
158
|
-
maxArrayLength:
|
|
159
|
-
maxByteStringLength:
|
|
157
|
+
maxStringLength: 16 * 1024 * 1024,
|
|
158
|
+
maxArrayLength: 1024 * 1024,
|
|
159
|
+
maxByteStringLength: 16 * 1024 * 1024,
|
|
160
160
|
maxQueryContinuationPoints: 0,
|
|
161
161
|
|
|
162
162
|
minSupportedSampleRate: 100,
|
|
@@ -245,7 +245,8 @@ export class ServerCapabilities implements IServerCapabilities {
|
|
|
245
245
|
// new in 1.05
|
|
246
246
|
this.maxSessions = options.maxSessions || defaultServerCapabilities.maxSessions;
|
|
247
247
|
|
|
248
|
-
this.maxSubscriptionsPerSession =
|
|
248
|
+
this.maxSubscriptionsPerSession =
|
|
249
|
+
options.maxSubscriptionsPerSession || defaultServerCapabilities.maxSubscriptionsPerSession;
|
|
249
250
|
this.maxSubscriptions = options.maxSubscriptions || defaultServerCapabilities.maxSubscriptions;
|
|
250
251
|
this.maxMonitoredItems = options.maxMonitoredItems || defaultServerCapabilities.maxMonitoredItems;
|
|
251
252
|
this.maxMonitoredItemsPerSubscription =
|
package/source/server_engine.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { EventEmitter } from "events";
|
|
|
5
5
|
import * as async from "async";
|
|
6
6
|
import * as chalk from "chalk";
|
|
7
7
|
import { assert } from "node-opcua-assert";
|
|
8
|
-
|
|
8
|
+
import { BinaryStream} from "node-opcua-binary-stream";
|
|
9
9
|
import {
|
|
10
10
|
addElement,
|
|
11
11
|
AddressSpace,
|
|
@@ -399,6 +399,8 @@ export class ServerEngine extends EventEmitter {
|
|
|
399
399
|
Object.values(this._sessions).forEach((session: ServerSession) => {
|
|
400
400
|
counter += session.currentSubscriptionCount;
|
|
401
401
|
});
|
|
402
|
+
// we also need to add the orphan subscriptions
|
|
403
|
+
counter += this._orphanPublishEngine ? this._orphanPublishEngine .subscriptions.length : 0;
|
|
402
404
|
return counter;
|
|
403
405
|
});
|
|
404
406
|
|
|
@@ -1007,15 +1009,15 @@ export class ServerEngine extends EventEmitter {
|
|
|
1007
1009
|
);
|
|
1008
1010
|
|
|
1009
1011
|
bindStandardScalar(VariableIds.Server_ServerCapabilities_MaxArrayLength, DataType.UInt32, () => {
|
|
1010
|
-
return this.serverCapabilities.maxArrayLength;
|
|
1012
|
+
return Math.min(this.serverCapabilities.maxArrayLength, Variant.maxArrayLength);
|
|
1011
1013
|
});
|
|
1012
1014
|
|
|
1013
1015
|
bindStandardScalar(VariableIds.Server_ServerCapabilities_MaxStringLength, DataType.UInt32, () => {
|
|
1014
|
-
return this.serverCapabilities.maxStringLength;
|
|
1016
|
+
return Math.min(this.serverCapabilities.maxStringLength, BinaryStream.maxStringLength);
|
|
1015
1017
|
});
|
|
1016
1018
|
|
|
1017
1019
|
bindStandardScalar(VariableIds.Server_ServerCapabilities_MaxByteStringLength, DataType.UInt32, () => {
|
|
1018
|
-
return this.serverCapabilities.maxByteStringLength;
|
|
1020
|
+
return Math.min(this.serverCapabilities.maxByteStringLength, BinaryStream.maxByteStringLength);
|
|
1019
1021
|
});
|
|
1020
1022
|
|
|
1021
1023
|
const bindOperationLimits = (operationLimits: OperationLimits) => {
|
|
@@ -1598,13 +1600,17 @@ export class ServerEngine extends EventEmitter {
|
|
|
1598
1600
|
});
|
|
1599
1601
|
}
|
|
1600
1602
|
|
|
1601
|
-
public
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1603
|
+
public getOldestInactiveSession(): ServerSession | null {
|
|
1604
|
+
// search screwed or closed session first
|
|
1605
|
+
let tmp = Object.values(this._sessions).filter(
|
|
1606
|
+
(session1: ServerSession) =>
|
|
1607
|
+
session1.status === "screwed" || session1.status === "disposed" || session1.status === "closed"
|
|
1608
|
+
);
|
|
1605
1609
|
if (tmp.length === 0) {
|
|
1606
|
-
|
|
1610
|
+
// if none available, tap into the session that are not yet activated
|
|
1611
|
+
tmp = Object.values(this._sessions).filter((session1: ServerSession) => session1.status === "new");
|
|
1607
1612
|
}
|
|
1613
|
+
if (tmp.length === 0) return null;
|
|
1608
1614
|
let session = tmp[0];
|
|
1609
1615
|
for (let i = 1; i < tmp.length; i++) {
|
|
1610
1616
|
const c = tmp[i];
|
|
@@ -1812,10 +1818,6 @@ export class ServerEngine extends EventEmitter {
|
|
|
1812
1818
|
if (!subscription) {
|
|
1813
1819
|
return new TransferResult({ statusCode: StatusCodes.BadSubscriptionIdInvalid });
|
|
1814
1820
|
}
|
|
1815
|
-
// istanbul ignore next
|
|
1816
|
-
if (!subscription.$session) {
|
|
1817
|
-
return new TransferResult({ statusCode: StatusCodes.BadInternalError });
|
|
1818
|
-
}
|
|
1819
1821
|
|
|
1820
1822
|
// check that session have same userIdentity
|
|
1821
1823
|
if (!sessionsCompatibleForTransfer(subscription.$session, session)) {
|
|
@@ -1846,9 +1848,11 @@ export class ServerEngine extends EventEmitter {
|
|
|
1846
1848
|
|
|
1847
1849
|
const nbSubscriptionBefore = session.publishEngine.subscriptionCount;
|
|
1848
1850
|
|
|
1849
|
-
subscription.$session
|
|
1851
|
+
if (subscription.$session) {
|
|
1852
|
+
subscription.$session._unexposeSubscriptionDiagnostics(subscription);
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1850
1855
|
await ServerSidePublishEngine.transferSubscription(subscription, session.publishEngine, sendInitialValues);
|
|
1851
|
-
|
|
1852
1856
|
subscription.$session = session;
|
|
1853
1857
|
|
|
1854
1858
|
session._exposeSubscriptionDiagnostics(subscription);
|
|
@@ -1983,7 +1987,7 @@ export class ServerEngine extends EventEmitter {
|
|
|
1983
1987
|
}
|
|
1984
1988
|
|
|
1985
1989
|
private _exposeSubscriptionDiagnostics(subscription: Subscription): void {
|
|
1986
|
-
debugLog("ServerEngine#_exposeSubscriptionDiagnostics");
|
|
1990
|
+
debugLog("ServerEngine#_exposeSubscriptionDiagnostics", subscription.subscriptionId);
|
|
1987
1991
|
const subscriptionDiagnosticsArray = this._getServerSubscriptionDiagnosticsArrayNode();
|
|
1988
1992
|
const subscriptionDiagnostics = subscription.subscriptionDiagnostics;
|
|
1989
1993
|
assert((subscriptionDiagnostics as any).$subscription === subscription);
|
|
@@ -1995,19 +1999,19 @@ export class ServerEngine extends EventEmitter {
|
|
|
1995
1999
|
}
|
|
1996
2000
|
|
|
1997
2001
|
protected _unexposeSubscriptionDiagnostics(subscription: Subscription): void {
|
|
1998
|
-
const
|
|
2002
|
+
const serverSubscriptionDiagnosticsArray = this._getServerSubscriptionDiagnosticsArrayNode();
|
|
1999
2003
|
const subscriptionDiagnostics = subscription.subscriptionDiagnostics;
|
|
2000
2004
|
assert(subscriptionDiagnostics instanceof SubscriptionDiagnosticsDataType);
|
|
2001
|
-
if (subscriptionDiagnostics &&
|
|
2002
|
-
const node = (
|
|
2003
|
-
removeElement(
|
|
2005
|
+
if (subscriptionDiagnostics && serverSubscriptionDiagnosticsArray) {
|
|
2006
|
+
const node = (serverSubscriptionDiagnosticsArray as any)[subscription.id];
|
|
2007
|
+
removeElement(serverSubscriptionDiagnosticsArray, subscriptionDiagnostics);
|
|
2004
2008
|
/*assert(
|
|
2005
2009
|
!(subscriptionDiagnosticsArray as any)[subscription.id],
|
|
2006
2010
|
" subscription node must have been removed from subscriptionDiagnosticsArray"
|
|
2007
2011
|
);
|
|
2008
2012
|
*/
|
|
2009
2013
|
}
|
|
2010
|
-
debugLog("ServerEngine#_unexposeSubscriptionDiagnostics");
|
|
2014
|
+
debugLog("ServerEngine#_unexposeSubscriptionDiagnostics", subscription.subscriptionId);
|
|
2011
2015
|
}
|
|
2012
2016
|
|
|
2013
2017
|
/**
|
|
@@ -2200,16 +2204,14 @@ export class ServerEngine extends EventEmitter {
|
|
|
2200
2204
|
private _getServerSubscriptionDiagnosticsArrayNode(): UADynamicVariableArray<SubscriptionDiagnosticsDataType> | null {
|
|
2201
2205
|
// istanbul ignore next
|
|
2202
2206
|
if (!this.addressSpace) {
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
}
|
|
2207
|
+
doDebug && debugLog("ServerEngine#_getServerSubscriptionDiagnosticsArray : no addressSpace");
|
|
2208
|
+
|
|
2206
2209
|
return null; // no addressSpace
|
|
2207
2210
|
}
|
|
2208
2211
|
const subscriptionDiagnosticsType = this.addressSpace.findVariableType("SubscriptionDiagnosticsType");
|
|
2209
2212
|
if (!subscriptionDiagnosticsType) {
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
}
|
|
2213
|
+
doDebug &&
|
|
2214
|
+
debugLog("ServerEngine#_getServerSubscriptionDiagnosticsArray " + ": cannot find SubscriptionDiagnosticsType");
|
|
2213
2215
|
}
|
|
2214
2216
|
|
|
2215
2217
|
// SubscriptionDiagnosticsArray = i=2290
|