Skip to content

Commit

Permalink
Small changes for remote connection
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Apr 8, 2024
1 parent b28e15c commit 0a925f3
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 50 deletions.
66 changes: 45 additions & 21 deletions lib/adminCommonSocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,22 @@ function getCompactInstances(adapter) {
});
}

function getCompactSystemRepositories(adapter) {
return adapter.getForeignObjectAsync('system.repositories')
.then(obj => {
obj?.native?.repositories && Object.keys(obj.native.repositories)
.forEach(name => {
if (obj.native.repositories[name].json) {
// limit information to _repoInfo
obj.native.repositories[name].json = {
_repoInfo: obj.native.repositories[name].json._repoInfo,
};
}
});
return obj;
});
}

function getCompactAdapters(adapter) {
return adapter.getObjectViewAsync('system', 'adapter',
{startkey: `system.adapter.`, endkey: `system.adapter.\u9999`})
Expand All @@ -252,32 +268,39 @@ function getCompactAdapters(adapter) {

function sendToHost(adapter, host, command, message) {
return new Promise(resolve => {
if (!message && ALLOW_CACHE.includes(command) && cache[host + '_' + command]) {
if (Date.now() - cache[host + '_' + command].ts < 500) {
if (!message && ALLOW_CACHE.includes(command) && cache[`${host}_${command}`]) {
if (Date.now() - cache[`${host}_${command}`].ts < 500) {
resolve(JSON.parse(cache[host + '_' + command].res));
} else {
delete cache[host + '_' + command];
delete cache[`${host}_${command}`];
}
}

adapter.sendToHost(host, command, message, res => {
if (!message && ALLOW_CACHE.includes(command)) {
cache[host + '_' + command] = {ts: Date.now(), res: JSON.stringify(res)};
cacheGB = cacheGB || setInterval(() => {
const commands = Object.keys(cache);
commands.forEach(cmd => {
if (Date.now() - cache[cmd].ts > 500) {
delete cache[cmd];
adapter.getForeignStateAsync(`${host}.alive`)
.then(state => {
if (state?.val) {
adapter.sendToHost(host, command, message, res => {
if (!message && ALLOW_CACHE.includes(command)) {
cache[`${host}_${command}`] = {ts: Date.now(), res: JSON.stringify(res)};
cacheGB = cacheGB || setInterval(() => {
const commands = Object.keys(cache);
commands.forEach(cmd => {
if (Date.now() - cache[cmd].ts > 500) {
delete cache[cmd];
}
});
if (!commands.length) {
clearInterval(cacheGB);
cacheGB = null;
}
}, 2000);
}
resolve(res);
});
if (!commands.length) {
clearInterval(cacheGB);
cacheGB = null;
}
}, 2000);
}
resolve(res);
});
} else {
resolve({});
}
});
});
}

Expand Down Expand Up @@ -433,11 +456,11 @@ function readLogs(adapter, host) {
}
}
} else {
result = {error: 'no file loggers'};
result = { error: 'no file loggers' };
}
} catch (e) {
adapter.log.error(e);
result = {error: e};
result = { error: e };
}

result.error ? reject(result.error) : resolve(result.list);
Expand Down Expand Up @@ -722,5 +745,6 @@ module.exports = {
getHostByIp,
getListOfAllAdapters,
getAllObjects,
getCompactSystemRepositories,
commandsPermissions,
}
104 changes: 75 additions & 29 deletions lib/remote.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ class RemoteAccess {
return response;
}

async _getStateManyArgs(args, func) {
async _getStateManyArgs(args) {
const response = [];
for (let a = 0; a < args.length; a++) {
const id = args[a][0];
Expand All @@ -545,6 +545,21 @@ class RemoteAccess {
return response;
}

async _getObjectManyArgs(args) {
const response = [];
for (let a = 0; a < args.length; a++) {
const id = args[a][0];
try {
const result = await this.adapter.getForeignObjectAsync(id || '*');
response[a] = [null, result];
this.statesCache[id] = result;
} catch (error) {
response[a] = [error];
}
}
return response;
}

async _subscribeManyArgs(sid, args) {
const response = [];
for (let a = 0; a < args.length; a++) {
Expand Down Expand Up @@ -631,10 +646,24 @@ class RemoteAccess {
let packed = zlib.deflateSync(JSON.stringify(args)).toString('base64');

if (packed.length > MAX_IOT_MESSAGE_LENGTH) {
const [error, file, mimeType] = args;
if (writeUrl && !error) {
return this.uploadToServer(writeUrl, {file, mimeType}, true)
.then(done => ({ sid, d: [_type, id, name, done ? readUrl : ['Cannot upload']] }));
if (writeUrl) {
if (args.length === 3) {
const [error, file, mimeType] = args;
if (!error) {
return this.uploadToServer(writeUrl, { file, mimeType }, true)
.then(done => ({ sid, d: [_type, id, name, done ? readUrl : ['Cannot upload']] }));
}
} else if (args.length === 2) {
const [error, result] = args;
if (!error) {
return this.uploadToServer(writeUrl, { file: JSON.stringify(result), mimeType: 'application/json' }, true)
.then(done => ({ sid, d: [_type, id, name, done ? readUrl : ['Cannot upload']] }));
}
} else if (args.length === 1) {
const [result] = args;
return this.uploadToServer(writeUrl, { file: JSON.stringify(result), mimeType: 'application/json' }, true)
.then(done => ({ sid, d: [_type, id, name, done ? readUrl : ['Cannot upload']] }));
}
}
// too big message. Do not use iot for that and send directly to socket
/*const packets = []
Expand Down Expand Up @@ -713,9 +742,9 @@ class RemoteAccess {
}

if (message) {
const [_type, id, name, args] = message.d;
let promiseOne;
let promiseResult;
const [_type, id, name, args, readUrl] = message.d;
let promiseOne; // answer will be created automatically (error, result)
let promiseResult; // answer will be created by promise

if (this.adapter.config.remote && _type === MESSAGE_TYPES.MISSING) {
if (this.packets[id]) {
Expand Down Expand Up @@ -860,6 +889,8 @@ class RemoteAccess {
promiseMany = this._getStatesManyArgs(args);
} else if (name === 'getState') {
promiseMany = this._getStateManyArgs(args);
} else if (name === 'getObject') {
promiseMany = this._getObjectManyArgs(args);
} else if (name === 'subscribe' || name === 'subscribeStates') {
promiseMany = this._subscribeManyArgs(message.sid, args);
} else if (name === 'unsubscribe' || name === 'unsubscribeStates') {
Expand Down Expand Up @@ -908,8 +939,7 @@ class RemoteAccess {
})*/
.catch(error => ({sid: message.sid, d: [_type, id, name, [error]]}));
}
} else
if (this.handlers[name]) {
} else if (this.handlers[name]) {
if (!this.handlers[name].args) {
promiseOne = this.handlers[name].f();
} else if (this.handlers[name].args === 1) {
Expand Down Expand Up @@ -977,7 +1007,7 @@ class RemoteAccess {

this.adapter.log.level === 'debug' && this._showSubscribes(message.sid, 'log');

promiseOne = Promise.resolve({sid: message.sid, d: [_type, id, name, [null]]});
promiseOne = Promise.resolve({ sid: message.sid, d: [_type, id, name, [null]] });
} else if (name === 'DCT') { // disconnect
const socket = this.sockets[message.sid];
this.adapter.log.debug(`[REMOTE] ---- DISCONNECT ${message.sid}`);
Expand All @@ -1000,7 +1030,7 @@ class RemoteAccess {
}

this.adapter.log.level === 'debug' && this._showSubscribes(message.sid, 'stateChange');
promiseOne = Promise.resolve({sid: message.sid, d: [_type, id, name, [null]]});
promiseOne = Promise.resolve({ sid: message.sid, d: [_type, id, name, [null]] });
} else if (name === 'unsubscribe' || name === 'unsubscribeStates') {
const pattern = args[0];
if (pattern && typeof pattern === 'object' && pattern instanceof Array) {
Expand All @@ -1012,7 +1042,7 @@ class RemoteAccess {
}

this.adapter.log.level === 'debug' && this._showSubscribes(message.sid, 'stateChange');
promiseOne = Promise.resolve({sid: message.sid, d: [_type, id, name, [null]]});
promiseOne = Promise.resolve({ sid: message.sid, d: [_type, id, name, [null]] });
} else if (name === 'subscribeObjects') {
const pattern = args && args[0] ? args[0] : '*';
if (pattern && typeof pattern === 'object' && pattern instanceof Array) {
Expand All @@ -1024,7 +1054,7 @@ class RemoteAccess {
}

this.adapter.log.level === 'debug' && this._showSubscribes(message.sid, 'objectChange');
promiseOne = Promise.resolve({sid: message.sid, d: [_type, id, name, [null]]});
promiseOne = Promise.resolve({ sid: message.sid, d: [_type, id, name, [null]] });
} else if (name === 'unsubscribeObjects') {
const pattern = args[0];
if (pattern && typeof pattern === 'object' && pattern instanceof Array) {
Expand All @@ -1044,7 +1074,7 @@ class RemoteAccess {
const fileName = args[1];
promiseResult = this.adapter.readFileAsync(adapter, fileName)
.then(data => this._sendResponse(message.sid, _type, id, name, [null, data.file, data.mimeType], message.wu, message.ru))
.catch(error => ({sid: message.sid, d: [_type, id, name, [error]]}));
.catch(error => ({ sid: message.sid, d: [_type, id, name, [error]] }));
} else if (name === 'readFile64') {
const adapter = args[0];
const fileName = args[1];
Expand Down Expand Up @@ -1074,12 +1104,24 @@ class RemoteAccess {
return this._sendResponse(message.sid, _type, id, name, [null, data64, data.mimeType], message.wu, message.ru);
})
.catch(error => ({sid: message.sid, d: [_type, id, name, [error]]}));
} else if (name === 'writeFile' || name === 'writeFile64') {
const [adr, fileName, data64, options] = args;
if (readUrl) {
promiseOne = axios(readUrl, { responseType: 'arraybuffer', validateStatus: status => status === 200, timeout: 15000 })
.then(response => this.adapter.writeFileAsync(adr, fileName, Buffer.from(response.data), options));
} else if (name === 'wirteFile') {
this.adapter.log.debug('writeFile deprecated. Please use writeFile64');
promiseOne = this.adapter.writeFileAsync(adr, fileName, data64, options);
} else if (name === 'wirteFile64') {
const buffer = Buffer.from(data64, 'base64');
promiseOne = this.adapter.writeFileAsync(adr, fileName, buffer, options);
}
} else if (name === 'getHistory') {
const _id = args[0];
const options = args[1];
promiseResult = this.adapter.getHistoryAsync(_id, options)
.then(data => this._sendResponse(message.sid, _type, id, name, [null, data.result, data.step, data.sessionId]))
.catch(error => ({sid: message.sid, d: [_type, id, name, [error]]}));
.then(data => this._sendResponse(message.sid, _type, id, name, [null, data.result, data.step, data.sessionId], message.wu, message.ru))
.catch(error => ({ sid: message.sid, d: [_type, id, name, [error]] }));
} else if (name === 'writeFile64' || name === 'writeFile') {
const [_adapter, fileName, data64, options] = args;
// Convert base 64 to buffer
Expand Down Expand Up @@ -1131,14 +1173,18 @@ class RemoteAccess {
promiseOne = AdminSocket.updateLicenses(this.adapter, args[0], args[1], this.adminObj);
} else if (name === 'getCompactInstances') {
promiseOne = AdminSocket.getCompactInstances(this.adapter);
} else if (name === 'getCompactSystemRepositories') {
promiseOne = AdminSocket.getCompactSystemRepositories(this.adapter);
} else if (name === 'getCompactAdapters') {
promiseOne = AdminSocket.getCompactAdapters(this.adapter);
} else if (name === 'getCompactInstalled') {
promiseOne = AdminSocket.getCompactInstalled(this.adapter, args[0] || this.adminObj.common.host);
promiseResult = AdminSocket.getCompactInstalled(this.adapter, args[0] || this.adminObj.common.host)
.then(data => ({ sid: message.sid, d: [_type, id, name, [data]] }));
} else if (name === 'getCompactSystemConfig') {
promiseOne = AdminSocket.getCompactSystemConfig(this.adapter);
} else if (name === 'getCompactRepository') {
promiseOne = AdminSocket.getCompactRepository(this.adapter, args[0] || this.adminObj.common.host);
promiseResult = AdminSocket.getCompactRepository(this.adapter, args[0] || this.adminObj.common.host)
.then(data => ({ sid: message.sid, d: [_type, id, name, [data]] }));
} else if (name === 'getCompactHosts') {
promiseOne = AdminSocket.getCompactHosts(this.adapter);
} else if (name === 'readLogs') {
Expand All @@ -1152,19 +1198,20 @@ class RemoteAccess {
} else if (name === 'listPermissions') {
promiseResult = AdminSocket.listPermissions(this.adapter)
.then(commandsPermissions => this._sendResponse(message.sid, _type, id, name, [commandsPermissions]))
.catch(error => ({sid: message.sid, d: [_type, id, name, [error]]}));
.catch(error => ({ sid: message.sid, d: [_type, id, name, [error]] }));
} else if (name === 'sendToHost') {
const [host, command, msg] = args;
this.adapter.log.debug(`[REMOTE] SEND_TO_HOST: ${command}`);
// check if the host is alive
promiseResult = AdminSocket.sendToHost(this.adapter, host, command, msg)
.then(data => this._sendResponse(message.sid, _type, id, name, [data]))
.then(data => this._sendResponse(message.sid, _type, id, name, [data], message.wu, message.ru))
.catch(error =>
({sid: message.sid, d: [_type, id, name, [error]]}));
({ sid: message.sid, d: [_type, id, name, [error]] }));
} else if (name === 'sendTo') {
const [adapterInstance, command, message] = args;
promiseResult = AdminSocket.sendTo(this.adapter, adapterInstance, command, message)
.then(data => this._sendResponse(message.sid, _type, id, name, [data]))
.catch(error => ({sid: message.sid, d: [_type, id, name, [error]]}));
.then(data => this._sendResponse(message.sid, _type, id, name, [data], message.wu, message.ru))
.catch(error => ({ sid: message.sid, d: [_type, id, name, [error]] }));
} else if (name === 'getAllObjects') {
promiseOne = AdminSocket.getAllObjects(this.adapter);
}
Expand All @@ -1175,16 +1222,15 @@ class RemoteAccess {
promiseOne
.then(() => NONE) :
Promise.resolve(NONE);
} else
if (!promiseResult && promiseOne) {
} else if (!promiseResult && promiseOne) {
promiseResult = promiseOne
.then(result => this._sendResponse(message.sid, _type, id, name, [null, result]))
.catch(error => ({sid: message.sid, d: [_type, id, name, [error]]}));
.then(result => this._sendResponse(message.sid, _type, id, name, [null, result], message.wu, message.ru))
.catch(error => ({ sid: message.sid, d: [_type, id, name, [error]] }));
}

if (!promiseResult) {
this.adapter.log.warn(`[REMOTE] Received unknown command: ${name}`);
promiseResult = Promise.resolve({sid: message.sid, d: [_type, id, name, ['Unknown command']]});
promiseResult = Promise.resolve({ sid: message.sid, d: [_type, id, name, ['Unknown command']] });
}

return promiseResult
Expand Down

0 comments on commit 0a925f3

Please sign in to comment.