@iobroker/socket-classes 1.1.5 → 1.3.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.
- package/README.md +175 -84
- package/lib/socketCommands.js +141 -43
- package/lib/socketCommandsAdmin.js +37 -37
- package/lib/socketCommon.js +14 -10
- package/package.json +5 -4
package/lib/socketCommands.js
CHANGED
|
@@ -67,6 +67,7 @@ class SocketCommands {
|
|
|
67
67
|
this.commands = {};
|
|
68
68
|
this.subscribes = {};
|
|
69
69
|
this.logEnabled = false;
|
|
70
|
+
this.clientSubscribes = {};
|
|
70
71
|
|
|
71
72
|
this._updateSession = updateSession;
|
|
72
73
|
|
|
@@ -230,6 +231,20 @@ class SocketCommands {
|
|
|
230
231
|
return false;
|
|
231
232
|
}
|
|
232
233
|
|
|
234
|
+
publishInstanceMessage(socket, sourceInstance, messageType, data) {
|
|
235
|
+
if (this.clientSubscribes[socket.id] &&
|
|
236
|
+
this.clientSubscribes[socket.id][sourceInstance] &&
|
|
237
|
+
this.clientSubscribes[socket.id][sourceInstance].includes(messageType)
|
|
238
|
+
) {
|
|
239
|
+
socket.emit('im', messageType, sourceInstance, data);
|
|
240
|
+
return true;
|
|
241
|
+
} else {
|
|
242
|
+
// inform instance about missing subscription
|
|
243
|
+
this.adapter.sendTo(sourceInstance, 'clientSubscribeError', {type: messageType, sid: socket.id});
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
233
248
|
_showSubscribes(socket, type) {
|
|
234
249
|
if (socket && socket.subscribe) {
|
|
235
250
|
const s = socket.subscribe[type] || [];
|
|
@@ -264,7 +279,13 @@ class SocketCommands {
|
|
|
264
279
|
key = pattern;
|
|
265
280
|
}
|
|
266
281
|
|
|
267
|
-
|
|
282
|
+
try {
|
|
283
|
+
p = pattern2RegEx(key);
|
|
284
|
+
} catch (e) {
|
|
285
|
+
this.adapter.log.error(`Invalid pattern on subscribe: ${e.message}`)
|
|
286
|
+
return
|
|
287
|
+
}
|
|
288
|
+
|
|
268
289
|
if (p === null) {
|
|
269
290
|
return this.adapter.log.warn('Empty pattern on subscribe!');
|
|
270
291
|
}
|
|
@@ -293,8 +314,8 @@ class SocketCommands {
|
|
|
293
314
|
this.logEnabled = true;
|
|
294
315
|
this.adapter.requireLog(true, options);
|
|
295
316
|
}
|
|
296
|
-
} else if (type === 'fileChange') {
|
|
297
|
-
|
|
317
|
+
} else if (type === 'fileChange' && this.adapter.subscribeForeignFiles) {
|
|
318
|
+
this.adapter.subscribeForeignFiles(pattern, patternFile, options);
|
|
298
319
|
}
|
|
299
320
|
} else {
|
|
300
321
|
this.subscribes[type][key]++;
|
|
@@ -358,7 +379,7 @@ class SocketCommands {
|
|
|
358
379
|
}
|
|
359
380
|
}
|
|
360
381
|
} else if (key) {
|
|
361
|
-
// Remove pattern from global list
|
|
382
|
+
// Remove a pattern from a global list
|
|
362
383
|
if (this.subscribes[type][key] !== undefined) {
|
|
363
384
|
this.subscribes[type][key]--;
|
|
364
385
|
if (this.subscribes[type][key] <= 0) {
|
|
@@ -445,6 +466,8 @@ class SocketCommands {
|
|
|
445
466
|
if (!socket || !socket.subscribe) {
|
|
446
467
|
return;
|
|
447
468
|
}
|
|
469
|
+
// inform all instances about disconnected socket
|
|
470
|
+
this._informAboutDisconnect(socket.id);
|
|
448
471
|
|
|
449
472
|
if (!type) {
|
|
450
473
|
// all
|
|
@@ -689,10 +712,10 @@ class SocketCommands {
|
|
|
689
712
|
|
|
690
713
|
// commands
|
|
691
714
|
this.commands['sendTo'] = (socket, adapterInstance, command, message, callback) => {
|
|
692
|
-
// Send message to specific instance
|
|
715
|
+
// Send the message to specific instance
|
|
693
716
|
// @param {string} adapterInstance - instance name, e.g. `history.0`
|
|
694
717
|
// @param {string} command - command name
|
|
695
|
-
// @param {object} message - message is instance dependent
|
|
718
|
+
// @param {object} message - the message is instance dependent
|
|
696
719
|
// @param {function} callback - `function (result)`
|
|
697
720
|
if (this._checkPermissions(socket, 'sendTo', callback, command)) {
|
|
698
721
|
try {
|
|
@@ -709,11 +732,11 @@ class SocketCommands {
|
|
|
709
732
|
const protectedCommands = ['cmdExec', 'getLocationOnDisk', 'getDiagData', 'getDevList', 'delLogs', 'writeDirAsZip', 'writeObjectsAsZip', 'readObjectsAsZip', 'checkLogging', 'updateMultihost', 'rebuildAdapter'];
|
|
710
733
|
|
|
711
734
|
this.commands['sendToHost'] = (socket, host, command, message, callback) => {
|
|
712
|
-
// Send message to specific host.
|
|
713
|
-
// Host can answer following commands: `cmdExec, getRepository, getInstalled, getInstalledAdapter, getVersion, getDiagData, getLocationOnDisk, getDevList, getLogs, getHostInfo, delLogs, readDirAsZip, writeDirAsZip, readObjectsAsZip, writeObjectsAsZip, checkLogging, updateMultihost`.
|
|
735
|
+
// Send a message to the specific host.
|
|
736
|
+
// Host can answer to the following commands: `cmdExec, getRepository, getInstalled, getInstalledAdapter, getVersion, getDiagData, getLocationOnDisk, getDevList, getLogs, getHostInfo, delLogs, readDirAsZip, writeDirAsZip, readObjectsAsZip, writeObjectsAsZip, checkLogging, updateMultihost`.
|
|
714
737
|
// @param {string} host - instance name, e.g. `history.0`
|
|
715
738
|
// @param {string} command - command name
|
|
716
|
-
// @param {object} message - message is command
|
|
739
|
+
// @param {object} message - the message is command-specific
|
|
717
740
|
// @param {function} callback - `function (result)`
|
|
718
741
|
if (this._checkPermissions(socket, protectedCommands.includes(command) ? 'cmdExec' : 'sendToHost', callback, command)) {
|
|
719
742
|
// Try to decode this file locally as redis has a limitation for files bigger than 20MB
|
|
@@ -731,7 +754,7 @@ class SocketCommands {
|
|
|
731
754
|
zipFiles
|
|
732
755
|
.writeDirAsZip(
|
|
733
756
|
this.adapter, // normally we have to pass here the internal "objects" object, but as
|
|
734
|
-
// only writeFile is used, and it has the same name we can pass here the
|
|
757
|
+
// only writeFile is used, and it has the same name, we can pass here the
|
|
735
758
|
// adapter, which has the function with the same name and arguments
|
|
736
759
|
message.id,
|
|
737
760
|
message.name,
|
|
@@ -757,7 +780,7 @@ class SocketCommands {
|
|
|
757
780
|
};
|
|
758
781
|
|
|
759
782
|
this.commands['authEnabled'] = (socket, callback) => {
|
|
760
|
-
// Ask server is authentication enabled and if the user authenticated
|
|
783
|
+
// Ask server is authentication enabled, and if the user authenticated
|
|
761
784
|
// @param {function} callback - `function (isAuthenticationUsed, userName)`
|
|
762
785
|
if (this._checkPermissions(socket, 'authEnabled', callback)) {
|
|
763
786
|
if (typeof callback === 'function') {
|
|
@@ -797,7 +820,7 @@ class SocketCommands {
|
|
|
797
820
|
};
|
|
798
821
|
|
|
799
822
|
this.commands['getVersion'] = (socket, callback) => {
|
|
800
|
-
// Get adapter version. Not the socket-classes version!
|
|
823
|
+
// Get the adapter version. Not the socket-classes version!
|
|
801
824
|
// @param {function} callback - `function (error, adapterVersion, adapterName)`
|
|
802
825
|
if (this._checkPermissions(socket, 'getVersion', callback)) {
|
|
803
826
|
if (typeof callback === 'function') {
|
|
@@ -826,7 +849,7 @@ class SocketCommands {
|
|
|
826
849
|
this.commands['readFile'] = (socket, _adapter, fileName, callback) => {
|
|
827
850
|
// Read file from ioBroker DB
|
|
828
851
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
829
|
-
// @param {string} fileName - file name, e.g `main/vis-views.json`
|
|
852
|
+
// @param {string} fileName - file name, e.g. `main/vis-views.json`
|
|
830
853
|
// @param {function} callback - `function (error, data, mimeType)`
|
|
831
854
|
if (this._checkPermissions(socket, 'readFile', callback, fileName)) {
|
|
832
855
|
try {
|
|
@@ -842,7 +865,7 @@ class SocketCommands {
|
|
|
842
865
|
this.commands['readFile64'] = (socket, _adapter, fileName, callback) => {
|
|
843
866
|
// Read file from ioBroker DB as base64 string
|
|
844
867
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
845
|
-
// @param {string} fileName - file name, e.g `main/vis-views.json`
|
|
868
|
+
// @param {string} fileName - file name, e.g. `main/vis-views.json`
|
|
846
869
|
// @param {function} callback - `function (error, base64, mimeType)`
|
|
847
870
|
if (this._checkPermissions(socket, 'readFile64', callback, fileName)) {
|
|
848
871
|
try {
|
|
@@ -881,7 +904,7 @@ class SocketCommands {
|
|
|
881
904
|
this.commands['writeFile64'] = (socket, _adapter, fileName, data64, options, callback) => {
|
|
882
905
|
// Write file into ioBroker DB as base64 string
|
|
883
906
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
884
|
-
// @param {string} fileName - file name, e.g `main/vis-views.json`
|
|
907
|
+
// @param {string} fileName - file name, e.g. `main/vis-views.json`
|
|
885
908
|
// @param {string} data64 - file content as base64 string
|
|
886
909
|
// @param {object} options - optional `{mode: 0x0644}`
|
|
887
910
|
// @param {function} callback - `function (error)`
|
|
@@ -914,7 +937,7 @@ class SocketCommands {
|
|
|
914
937
|
this.commands['writeFile'] = (socket, _adapter, fileName, data, options, callback) => {
|
|
915
938
|
// Write file into ioBroker DB as text **DEPRECATED**
|
|
916
939
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
917
|
-
// @param {string} fileName - file name, e.g `main/vis-views.json`
|
|
940
|
+
// @param {string} fileName - file name, e.g. `main/vis-views.json`
|
|
918
941
|
// @param {string} data64 - file content as base64 string
|
|
919
942
|
// @param {object} options - optional `{mode: 0x644}`
|
|
920
943
|
// @param {function} callback - `function (error)`
|
|
@@ -940,7 +963,7 @@ class SocketCommands {
|
|
|
940
963
|
this.commands['unlink'] = (socket, _adapter, name, callback) => {
|
|
941
964
|
// Delete file in ioBroker DB
|
|
942
965
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
943
|
-
// @param {string} name - file name, e.g `main/vis-views.json`
|
|
966
|
+
// @param {string} name - file name, e.g. `main/vis-views.json`
|
|
944
967
|
// @param {function} callback - `function (error)`
|
|
945
968
|
if (this._checkPermissions(socket, 'unlink', callback, name)) {
|
|
946
969
|
try {
|
|
@@ -957,7 +980,7 @@ class SocketCommands {
|
|
|
957
980
|
this.commands['deleteFile'] = (socket, _adapter, name, callback) => {
|
|
958
981
|
// Delete file in ioBroker DB (same as unlink, but only for files)
|
|
959
982
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
960
|
-
// @param {string} name - file name, e.g `main/vis-views.json`
|
|
983
|
+
// @param {string} name - file name, e.g. `main/vis-views.json`
|
|
961
984
|
// @param {function} callback - `function (error)`
|
|
962
985
|
if (this._checkPermissions(socket, 'unlink', callback, name)) {
|
|
963
986
|
try {
|
|
@@ -973,7 +996,7 @@ class SocketCommands {
|
|
|
973
996
|
this.commands['deleteFolder'] = (socket, _adapter, name, callback) => {
|
|
974
997
|
// Delete file in ioBroker DB (same as unlink, but only for folders)
|
|
975
998
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
976
|
-
// @param {string} name - folder name, e.g `main`
|
|
999
|
+
// @param {string} name - folder name, e.g. `main`
|
|
977
1000
|
// @param {function} callback - `function (error)`
|
|
978
1001
|
if (this._checkPermissions(socket, 'unlink', callback, name)) {
|
|
979
1002
|
try {
|
|
@@ -990,8 +1013,8 @@ class SocketCommands {
|
|
|
990
1013
|
this.commands['renameFile'] = (socket, _adapter, oldName, newName, callback) => {
|
|
991
1014
|
// Rename file in ioBroker DB
|
|
992
1015
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
993
|
-
// @param {string} oldName - current file name, e.g `main/vis-views.json`
|
|
994
|
-
// @param {string} newName - new file name, e.g `main/vis-views-new.json`
|
|
1016
|
+
// @param {string} oldName - current file name, e.g. `main/vis-views.json`
|
|
1017
|
+
// @param {string} newName - new file name, e.g. `main/vis-views-new.json`
|
|
995
1018
|
// @param {function} callback - `function (error)`
|
|
996
1019
|
if (this._checkPermissions(socket, 'rename', callback, oldName)) {
|
|
997
1020
|
try {
|
|
@@ -1007,8 +1030,8 @@ class SocketCommands {
|
|
|
1007
1030
|
this.commands['rename'] = (socket, _adapter, oldName, newName, callback) => {
|
|
1008
1031
|
// Rename file or folder in ioBroker DB
|
|
1009
1032
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
1010
|
-
// @param {string} oldName - current file name, e.g `main/vis-views.json`
|
|
1011
|
-
// @param {string} newName - new file name, e.g `main/vis-views-new.json`
|
|
1033
|
+
// @param {string} oldName - current file name, e.g. `main/vis-views.json`
|
|
1034
|
+
// @param {string} newName - new file name, e.g. `main/vis-views-new.json`
|
|
1012
1035
|
// @param {function} callback - `function (error)`
|
|
1013
1036
|
if (this._checkPermissions(socket, 'rename', callback, oldName)) {
|
|
1014
1037
|
try {
|
|
@@ -1025,7 +1048,7 @@ class SocketCommands {
|
|
|
1025
1048
|
this.commands['mkdir'] = (socket, _adapter, dirName, callback) => {
|
|
1026
1049
|
// Create folder in ioBroker DB
|
|
1027
1050
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
1028
|
-
// @param {string} dirName - desired folder name, e.g `main`
|
|
1051
|
+
// @param {string} dirName - desired folder name, e.g. `main`
|
|
1029
1052
|
// @param {function} callback - `function (error)`
|
|
1030
1053
|
if (this._checkPermissions(socket, 'mkdir', callback, dirName)) {
|
|
1031
1054
|
try {
|
|
@@ -1041,7 +1064,7 @@ class SocketCommands {
|
|
|
1041
1064
|
this.commands['readDir'] = (socket, _adapter, dirName, options, callback) => {
|
|
1042
1065
|
// Read content of folder in ioBroker DB
|
|
1043
1066
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
1044
|
-
// @param {string} dirName - folder name, e.g `main`
|
|
1067
|
+
// @param {string} dirName - folder name, e.g. `main`
|
|
1045
1068
|
// @param {object} options - optional `{filter: '*'}` or `{filter: '*.json'}`
|
|
1046
1069
|
// @param {function} callback - `function (error, files)` where `files` is an array of objects, like `{file: 'vis-views.json', isDir: false, stats: {size: 123}, modifiedAt: 1661336290090, acl: {owner: 'system.user.admin', ownerGroup: 'system.group.administrator', permissions: 1632, read: true, write: true}`
|
|
1047
1070
|
if (typeof options === 'function') {
|
|
@@ -1069,8 +1092,8 @@ class SocketCommands {
|
|
|
1069
1092
|
this.commands['chmodFile'] = (socket, _adapter, fileName, options, callback) => {
|
|
1070
1093
|
// Change file mode in ioBroker DB
|
|
1071
1094
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
1072
|
-
// @param {string} fileName - file name, e.g `main/vis-views.json`
|
|
1073
|
-
// @param {object} options - `{mode: 0x644}` or 0x644.
|
|
1095
|
+
// @param {string} fileName - file name, e.g. `main/vis-views.json`
|
|
1096
|
+
// @param {object} options - `{mode: 0x644}` or 0x644. The first digit is user, second group, third others. Bit 1 is `execute`, bit 2 is `write`, bit 3 is `read`
|
|
1074
1097
|
// @param {function} callback - `function (error)`
|
|
1075
1098
|
if (typeof options === 'function') {
|
|
1076
1099
|
callback = options;
|
|
@@ -1097,7 +1120,7 @@ class SocketCommands {
|
|
|
1097
1120
|
this.commands['chownFile'] = (socket, _adapter, fileName, options, callback) => {
|
|
1098
1121
|
// Change file owner in ioBroker DB
|
|
1099
1122
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
1100
|
-
// @param {string} fileName - file name, e.g `main/vis-views.json`
|
|
1123
|
+
// @param {string} fileName - file name, e.g. `main/vis-views.json`
|
|
1101
1124
|
// @param {object} options - `{owner: 'system.user.user', ownerGroup: ''system.group.administrator'}` or 'system.user.user'. If ownerGroup is not defined, it will be taken from owner.
|
|
1102
1125
|
// @param {function} callback - `function (error)`
|
|
1103
1126
|
if (this._checkPermissions(socket, 'chownFile', callback, fileName)) {
|
|
@@ -1114,9 +1137,9 @@ class SocketCommands {
|
|
|
1114
1137
|
};
|
|
1115
1138
|
|
|
1116
1139
|
this.commands['fileExists'] = (socket, _adapter, fileName, callback) => {
|
|
1117
|
-
//
|
|
1140
|
+
// Check if the file or folder exists in ioBroker DB
|
|
1118
1141
|
// @param {string} _adapter - instance name, e.g. `vis.0`
|
|
1119
|
-
// @param {string} fileName - file name, e.g `main/vis-views.json`
|
|
1142
|
+
// @param {string} fileName - file name, e.g. `main/vis-views.json`
|
|
1120
1143
|
// @param {function} callback - `function (error, isExist)`
|
|
1121
1144
|
if (this._checkPermissions(socket, 'fileExists', callback, fileName)) {
|
|
1122
1145
|
try {
|
|
@@ -1130,17 +1153,17 @@ class SocketCommands {
|
|
|
1130
1153
|
};
|
|
1131
1154
|
|
|
1132
1155
|
this.commands['subscribeFiles'] = (socket, id, pattern, callback) => {
|
|
1133
|
-
// Subscribe
|
|
1156
|
+
// Subscribe to file changes in ioBroker DB
|
|
1134
1157
|
// @param {string} id - instance name, e.g. `vis.0` or any object ID of type `meta`. `id` could have wildcards `*` too.
|
|
1135
|
-
// @param {string} pattern - file name pattern, e.g `main/*.json`
|
|
1158
|
+
// @param {string} pattern - file name pattern, e.g. `main/*.json`
|
|
1136
1159
|
// @param {function} callback - `function (error)`
|
|
1137
1160
|
return this._subscribeFiles(socket, id, pattern, callback);
|
|
1138
1161
|
}
|
|
1139
1162
|
|
|
1140
1163
|
this.commands['unsubscribeFiles'] = (socket, id, pattern, callback) => {
|
|
1141
|
-
// Unsubscribe
|
|
1164
|
+
// Unsubscribe from file changes in ioBroker DB
|
|
1142
1165
|
// @param {string} id - instance name, e.g. `vis.0` or any object ID of type `meta`. `id` could have wildcards `*` too.
|
|
1143
|
-
// @param {string} pattern - file name pattern, e.g `main/*.json`
|
|
1166
|
+
// @param {string} pattern - file name pattern, e.g. `main/*.json`
|
|
1144
1167
|
// @param {function} callback - `function (error)`
|
|
1145
1168
|
|
|
1146
1169
|
return this._unsubscribeFiles(socket, id, pattern, callback);
|
|
@@ -1148,7 +1171,7 @@ class SocketCommands {
|
|
|
1148
1171
|
|
|
1149
1172
|
this.commands['getAdapterInstances'] = (socket, adapterName, callback) => {
|
|
1150
1173
|
// Read all instances of the given adapter, or all instances of all adapters if adapterName is not defined
|
|
1151
|
-
// @param {string} adapterName - optional adapter name, e.g `history`.
|
|
1174
|
+
// @param {string} adapterName - optional adapter name, e.g. `history`.
|
|
1152
1175
|
// @param {function} callback - `function (error, instanceList)`, where instanceList is an array of instance objects, e.g. `{_id: 'system.adapter.history.0', common: {name: 'history', ...}, native: {...}}`
|
|
1153
1176
|
if (typeof callback === 'function') {
|
|
1154
1177
|
if (this._checkPermissions(socket, 'getObject', callback)) {
|
|
@@ -1212,7 +1235,7 @@ class SocketCommands {
|
|
|
1212
1235
|
|
|
1213
1236
|
this.commands['getForeignStates'] = (socket, pattern, callback) => {
|
|
1214
1237
|
// Read all states (which might not belong to this adapter) which match the given pattern
|
|
1215
|
-
// @param {string} pattern - pattern like
|
|
1238
|
+
// @param {string} pattern - pattern like `system.adapter.*` or array of state IDs
|
|
1216
1239
|
// @param {function} callback - `function (error)`
|
|
1217
1240
|
if (this._checkPermissions(socket, 'getStates', callback)) {
|
|
1218
1241
|
if (typeof callback === 'function') {
|
|
@@ -1320,7 +1343,7 @@ class SocketCommands {
|
|
|
1320
1343
|
this.commands['setBinaryState'] = (socket, id, base64, callback) => {
|
|
1321
1344
|
// Write one binary state.
|
|
1322
1345
|
// @param {string} id - State ID like, 'javascript.0.binary'
|
|
1323
|
-
// @param {string} base64 - State value as base64 string. Binary states
|
|
1346
|
+
// @param {string} base64 - State value as base64 string. Binary states have no acknowledged flag.
|
|
1324
1347
|
// @param {function} callback - `function (error)`
|
|
1325
1348
|
if (this._checkPermissions(socket, 'setState', callback, id)) {
|
|
1326
1349
|
if (typeof callback === 'function') {
|
|
@@ -1350,14 +1373,14 @@ class SocketCommands {
|
|
|
1350
1373
|
};
|
|
1351
1374
|
|
|
1352
1375
|
this.commands['subscribe'] = (socket, pattern, callback) => {
|
|
1353
|
-
// Subscribe
|
|
1376
|
+
// Subscribe to state changes by pattern. The events will come as 'stateChange' events to the socket.
|
|
1354
1377
|
// @param {string} pattern - pattern like 'system.adapter.*' or array of states like ['system.adapter.admin.0.memRss', 'system.adapter.admin.0.memHeapTotal']
|
|
1355
1378
|
// @param {function} callback - `function (error)`
|
|
1356
1379
|
return this._subscribeStates(socket, pattern, callback);
|
|
1357
1380
|
};
|
|
1358
1381
|
|
|
1359
1382
|
this.commands['subscribeStates'] = (socket, pattern, callback) => {
|
|
1360
|
-
// Subscribe
|
|
1383
|
+
// Subscribe to state changes by pattern. Same as `subscribe`. The events will come as 'stateChange' events to the socket.
|
|
1361
1384
|
// @param {string} pattern - pattern like 'system.adapter.*' or array of states like ['system.adapter.admin.0.memRss', 'system.adapter.admin.0.memHeapTotal']
|
|
1362
1385
|
// @param {function} callback - `function (error)`
|
|
1363
1386
|
return this._subscribeStates(socket, pattern, callback);
|
|
@@ -1401,11 +1424,30 @@ class SocketCommands {
|
|
|
1401
1424
|
|
|
1402
1425
|
// not admin version of "all objects"
|
|
1403
1426
|
// this function is overloaded in admin
|
|
1404
|
-
this.commands['getObjects'] = (socket, callback) => {
|
|
1427
|
+
this.commands['getObjects'] = (socket, list, callback) => {
|
|
1405
1428
|
// Get all objects that are relevant for web: all states and enums with rooms
|
|
1406
1429
|
// @param {string} id - object ID.
|
|
1430
|
+
// @param {string[]} list - optional list of IDs.
|
|
1407
1431
|
// @param {function} callback - `function (error, obj)`
|
|
1408
|
-
if (
|
|
1432
|
+
if (typeof list === 'function') {
|
|
1433
|
+
callback = list;
|
|
1434
|
+
list = null;
|
|
1435
|
+
}
|
|
1436
|
+
if (list && list.length) {
|
|
1437
|
+
if (this._checkPermissions(socket, 'getObject', callback)) {
|
|
1438
|
+
if (typeof callback === 'function') {
|
|
1439
|
+
try {
|
|
1440
|
+
this.adapter.getForeignObjects(list, {user: socket._acl.user}, (error, objs) =>
|
|
1441
|
+
SocketCommands._fixCallback(callback, error, objs));
|
|
1442
|
+
} catch (error) {
|
|
1443
|
+
this.adapter.log.error(`[getObjects] ERROR: ${error.toString()}`);
|
|
1444
|
+
SocketCommands._fixCallback(callback, error);
|
|
1445
|
+
}
|
|
1446
|
+
} else {
|
|
1447
|
+
this.adapter.log.warn('[getObjects] Invalid callback');
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
} else if (this._checkPermissions(socket, 'getObjects', callback)) {
|
|
1409
1451
|
try {
|
|
1410
1452
|
if (typeof callback === 'function') {
|
|
1411
1453
|
this.adapter.getForeignObjects('*', 'state', 'rooms', {user: socket._acl.user}, async (error, objs) => {
|
|
@@ -1437,7 +1479,7 @@ class SocketCommands {
|
|
|
1437
1479
|
};
|
|
1438
1480
|
|
|
1439
1481
|
this.commands['subscribeObjects'] = (socket, pattern, callback) => {
|
|
1440
|
-
// Subscribe
|
|
1482
|
+
// Subscribe to object changes by pattern. The events will come as 'objectChange' events to the socket.
|
|
1441
1483
|
// @param {string} pattern - pattern like 'system.adapter.*' or array of IDs like ['system.adapter.admin.0.memRss', 'system.adapter.admin.0.memHeapTotal']
|
|
1442
1484
|
// @param {function} callback - `function (error)`
|
|
1443
1485
|
if (this._checkPermissions(socket, 'subscribeObjects', callback, pattern)) {
|
|
@@ -1461,7 +1503,7 @@ class SocketCommands {
|
|
|
1461
1503
|
};
|
|
1462
1504
|
|
|
1463
1505
|
this.commands['unsubscribeObjects'] = (socket, pattern, callback) => {
|
|
1464
|
-
// Unsubscribe
|
|
1506
|
+
// Unsubscribe from object changes by pattern.
|
|
1465
1507
|
// @param {string} pattern - pattern like 'system.adapter.*' or array of IDs like ['system.adapter.admin.0.memRss', 'system.adapter.admin.0.memHeapTotal']
|
|
1466
1508
|
// @param {function} callback - `function (error)`
|
|
1467
1509
|
if (this._checkPermissions(socket, 'unsubscribeObjects', callback, pattern)) {
|
|
@@ -1540,6 +1582,48 @@ class SocketCommands {
|
|
|
1540
1582
|
SocketCommands._fixCallback(callback, SocketCommands.ERROR_PERMISSION);
|
|
1541
1583
|
}
|
|
1542
1584
|
};
|
|
1585
|
+
|
|
1586
|
+
this.commands['clientSubscribe'] = (socket, targetInstance, messageType, data, callback) => {
|
|
1587
|
+
// Client informs specific instance about subscription on its messages. After subscription the socket will receive "im" messages from desired instance
|
|
1588
|
+
// @param {string} targetInstance - instance name, e.g. "cameras.0"
|
|
1589
|
+
// @param {string} messageType - message type, e.g. "startRecording/cam1"
|
|
1590
|
+
// @param {object} data - optional data object, e.g. {width: 640, height: 480}
|
|
1591
|
+
// @param {function} callback - `function (error, result)`, target instance MUST acknowledge the subscription and return some object as result
|
|
1592
|
+
if (typeof data === 'function') {
|
|
1593
|
+
callback = data;
|
|
1594
|
+
data = null;
|
|
1595
|
+
}
|
|
1596
|
+
const sid = socket.id;
|
|
1597
|
+
// GUI subscribes for messages from targetInstance
|
|
1598
|
+
this.clientSubscribes[sid] = this.clientSubscribes[sid] || {};
|
|
1599
|
+
this.clientSubscribes[sid][targetInstance] = this.clientSubscribes[sid][targetInstance] || [];
|
|
1600
|
+
if (!this.clientSubscribes[sid][targetInstance].includes(messageType)) {
|
|
1601
|
+
this.clientSubscribes[sid][targetInstance].push(messageType);
|
|
1602
|
+
}
|
|
1603
|
+
// inform instance about new subscription
|
|
1604
|
+
this.adapter.sendTo(targetInstance, 'clientSubscribe', {type: messageType, sid, data}, result =>
|
|
1605
|
+
SocketCommands._fixCallback(callback, null, result));
|
|
1606
|
+
};
|
|
1607
|
+
|
|
1608
|
+
this.commands['clientUnsubscribe'] = (socket, targetInstance, messageType, callback) => {
|
|
1609
|
+
// Client unsubscribes from specific instance's messages
|
|
1610
|
+
// @param {string} targetInstance - instance name, e.g. "cameras.0"
|
|
1611
|
+
// @param {string} messageType - message type, e.g. "startRecording/cam1"
|
|
1612
|
+
// @param {function} callback - `function (error, wasSubscribed)`, target instance MUST NOT acknowledge the un-subscription
|
|
1613
|
+
const sid = socket.id;
|
|
1614
|
+
// GUI unsubscribes for messages from targetInstance
|
|
1615
|
+
if (this.clientSubscribes[sid] && this.clientSubscribes[sid][targetInstance]) {
|
|
1616
|
+
const pos = this.clientSubscribes[sid][targetInstance].indexOf(messageType);
|
|
1617
|
+
if (pos !== -1) {
|
|
1618
|
+
this.clientSubscribes[sid][targetInstance].splice(pos, 1);
|
|
1619
|
+
// inform instance about unsubscription
|
|
1620
|
+
this.adapter.sendTo(targetInstance, 'clientUnsubscribe', {type: [messageType], sid});
|
|
1621
|
+
SocketCommands._fixCallback(callback, null, true);
|
|
1622
|
+
return;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
SocketCommands._fixCallback(callback, null, false);
|
|
1626
|
+
};
|
|
1543
1627
|
}
|
|
1544
1628
|
|
|
1545
1629
|
_initCommands() {
|
|
@@ -1549,6 +1633,20 @@ class SocketCommands {
|
|
|
1549
1633
|
this.__initCommandsFiles();
|
|
1550
1634
|
}
|
|
1551
1635
|
|
|
1636
|
+
_informAboutDisconnect(socketId) {
|
|
1637
|
+
// say to all instances, that this socket was disconnected
|
|
1638
|
+
if (this.clientSubscribes[socketId]) {
|
|
1639
|
+
Object.keys(this.clientSubscribes[socketId]).forEach(targetInstance => {
|
|
1640
|
+
this.adapter.sendTo(targetInstance, 'clientUnsubscribe', {
|
|
1641
|
+
message: this.clientSubscribes[socketId][targetInstance],
|
|
1642
|
+
sid: socketId,
|
|
1643
|
+
provider: this.adapter.namespace
|
|
1644
|
+
});
|
|
1645
|
+
});
|
|
1646
|
+
delete this.clientSubscribes[socketId];
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1552
1650
|
applyCommands(socket) {
|
|
1553
1651
|
Object.keys(this.commands)
|
|
1554
1652
|
.forEach(command => socket.on(command, (...args) => {
|