-"use strict";
+'use strict';
const io = require('socket.io');
const JSEncryptLib = require('./jsencrypt');
const localClientIps = [
'127.0.0.1'
];
const TAG = '[DeviceHome][relay-server.js]'
+const TAG_HOST = `${TAG}[Host]`;
+const TAG_CLIENT = `${TAG}[Client]`;
const TO_ALL = 100;
+let receiver = {};
+let sender = {};
let remoteClients = {};
-let localClients = {};
let localClientMessageQueues = {};
+let globalClientPublicKeys = {};
var getIp = function(rawIp) {
- return rawIp.slice(rawIp.lastIndexOf(":") + 1);
+ return rawIp.slice(rawIp.lastIndexOf(':') + 1);
}
var decrypt = function(msg, ws) {
const crypto = new JSEncryptLib();
console.log(`${TAG}[encrypt] plain : ${msg}`);
return serverCrypto.encrypt(msg);
}
+var OnReceived = function (msg) {
+ console.log(`${TAG_HOST}[OnReceived] msg[0].key : ${msg[0].key}`);
+ console.log(`${TAG_HOST}[OnReceived] msg[0].value : ${msg[0].value}`);
+ const pkgId = msg[0].key;
+ msg = JSON.parse(msg[0].value);
+ if (msg.type === 'AppId') {
+ const appId = msg.data;
+ console.log(`${TAG_HOST}[OnReceived] Initialize msg port sender : ${appId}`);
+ if (!sender[pkgId])
+ sender[pkgId] = {};
+ sender[pkgId].messagePort = tizen.messageport.requestRemoteMessagePort(appId, `${pkgId}.Companion`);
+ if (localClientMessageQueues[pkgId] !== undefined) {
+ while (localClientMessageQueues[pkgId].length) {
+ const msg = localClientMessageQueues[pkgId].shift();
+ console.log(`${TAG_HOST} #################################`);
+ console.log(`${TAG_HOST} send pending msg : ${msg}`);
+ console.log(`${TAG_HOST} #################################`);
+ sender[pkgId].messagePort.sendMessage([{
+ key: pkgId,
+ value: msg,
+ }]);
+ }
+ }
+ } else {
+ console.log(`${TAG_HOST}[OnReceived] Send message from msg port to web socket`);
+ if (!remoteClients || !remoteClients[pkgId].length) {
+ console.log(`${TAG_HOST}[OnReceived] There's no available web socket remote clients`);
+ return;
+ }
+ const id = msg.id;
+ if (id === -1) {
+ console.log(`${TAG_HOST}[OnReceived] Handle message only on relay server`);
+ // Do what need to handle in relay server only
+ return;
+ }
+ console.log(`${TAG_HOST}[OnReceived] id : ${id}`);
+ if (id === TO_ALL) {
+ console.log(`${TAG_HOST}[OnReceived] Send message to all web sockets`);
+ console.log(`${TAG_HOST}[OnReceived] remoteClients length : ${remoteClients[pkgId].length}`);
+ for (let client of remoteClients[pkgId]) {
+ const encrypted = encrypt(JSON.stringify(msg), client, pkgId, globalClientPublicKeys);
+ if (encrypted === false || encrypted === null) {
+ console.log(`${TAG_HOST}[OnReceived] Failed to encrypt message!`);
+ return;
+ }
+ console.log(`${TAG_HOST}[OnReceived] encrypted : ${encrypted}`);
+ client.emit('d2d_message', encrypted);
+ }
+ } else {
+ console.log(`${TAG_HOST}[OnReceived] Send message to a web socket #${id}`);
+ if (id < remoteClients[pkgId].length) {
+ const encrypted = encrypt(JSON.stringify(msg), remoteClients[pkgId][id], pkgId, globalClientPublicKeys);
+ if (encrypted === false || encrypted === null) {
+ console.log(`${TAG_HOST}[OnReceived] Failed to encrypt message!`);
+ return;
+ }
+ console.log(`${TAG_HOST}[OnReceived] encrypted : ${encrypted}`);
+ remoteClients[pkgId][id].emit('d2d_message', encrypted);
+ }
+ }
+ }
+};
var addConnection = function(wsServer, pkgId, sessionMiddleware, clientPublicKeys) {
+ globalClientPublicKeys = clientPublicKeys;
+ // Host
+ console.log(`${TAG_HOST} Initialize msg port recevier : ${pkgId}.Companion`);
+ if (!receiver[pkgId])
+ receiver[pkgId] = {};
+ receiver[pkgId].messagePort = tizen.messageport.requestLocalMessagePort(`${pkgId}.Companion`);
+ receiver[pkgId].messagePortListener = receiver[pkgId].messagePort.addMessagePortListener(OnReceived.bind(this));
+
+ // Remote Client
+ console.log(`${TAG_CLIENT} Initialize client web socket`);
const namespace = wsServer.of(`/${pkgId}`);
namespace.use((socket, next) => {
sessionMiddleware(socket.request, {}, next);
});
namespace.on('connection', ws => {
- console.log(`${TAG} connection event : ${pkgId}`);
+ console.log(`${TAG_CLIENT} connection event : ${pkgId}`);
// In case of local client, remoteAddress will be ::1
// In case of remote client, remoteAddress will be ::ffff:ipaddress
// e.g.) ::ffff:192.168.0.21
- console.log(`${TAG} address : ${ws.handshake.address}`);
- console.log(`${TAG} url : ${ws.handshake.url}`);
- console.log(`${TAG} session id : ${ws.request.session.id}`);
+ console.log(`${TAG_CLIENT} address : ${ws.handshake.address}`);
+ console.log(`${TAG_CLIENT} url : ${ws.handshake.url}`);
+ console.log(`${TAG_CLIENT} session id : ${ws.request.session.id}`);
if (remoteClients[pkgId] === undefined)
remoteClients[pkgId] = [];
- if (localClientIps.includes(getIp(ws.handshake.address))) {
- const TAG_LOCAL = `${TAG}[Local]`;
- console.log(`${TAG_LOCAL} connected from local`);
- localClients[pkgId] = ws;
- console.log(`${TAG_LOCAL} remote length : ${remoteClients[pkgId].length}`);
-
- if (!remoteClients[pkgId].length) {
- console.log(`${TAG_LOCAL} connected : no remote-clients`);
- }
- if (localClientMessageQueues[pkgId] !== undefined) {
- while (localClientMessageQueues[pkgId].length) {
- const msg = localClientMessageQueues[pkgId].shift();
- console.log(`${TAG_LOCAL} #################################`);
- console.log(`${TAG_LOCAL} send pending msg : ${msg}`);
- console.log(`${TAG_LOCAL} #################################`);
- ws.emit('d2d_message', msg);
- }
- }
- ws.on('d2d_message', function(msg) {
- console.log(`${TAG_LOCAL} #################################`);
- console.log(`${TAG_LOCAL} on d2d message : ${msg}`);
- console.log(`${TAG_LOCAL} #################################`);
-
- let myPkgId = null;
- for (let key in localClients) {
- if (localClients[key] === ws) {
- myPkgId = key;
- break;
- }
- }
-
- let id = JSON.parse(msg).id;
- console.log(`${TAG_LOCAL} id : ${id}`);
- if (id == -1) {
- // Do what need to handle in relay server only
- return;
- }
- if (!remoteClients[myPkgId].length)
- return;
- if (id == TO_ALL) {
- console.log(`${TAG_LOCAL} remoteClients length : ${remoteClients[myPkgId].length}`);
- for (let client of remoteClients[myPkgId]) {
- const encrypted = encrypt(msg, client, myPkgId, clientPublicKeys);
- if (encrypted === false || encrypted === null) {
- console.log("Error: Failed to encrypt message");
- return;
- }
- console.log(`${TAG_LOCAL} encrypted : ${encrypted}`);
- client.emit('d2d_message', encrypted);
- }
- } else {
- console.log(`${TAG_LOCAL} id : ${id}`);
- if (id < remoteClients[myPkgId].length) {
- msg = encrypt(msg, remoteClients[myPkgId][id], myPkgId, clientPublicKeys);
- if (msg === false || msg === null) {
- console.log("Error: Failed to encrypt message");
- return;
- }
- console.log(`${TAG_LOCAL} encrypted : ${msg}`);
- remoteClients[myPkgId][id].emit('d2d_message', msg);
- }
- }
- });
- ws.on('disconnect', function(msg) {
- console.log(`${TAG_LOCAL}[close] #################################`);
- console.log(`${TAG_LOCAL}[close] on disconnect event : ${msg}`);
- console.log(`${TAG_LOCAL}[close] #################################`);
- let myPkgId = null;
- for (let key in localClients) {
- if (localClients[key] === ws) {
- myPkgId = key;
- break;
- }
- }
- localClients[myPkgId] = undefined;
- console.log(`${TAG_LOCAL}[close] remoteClients[${myPkgId}] : ${remoteClients[myPkgId]}`);
- for (let remoteClient of remoteClients[myPkgId]) {
- console.log(`${TAG}[close local client] sent local_client_disconnect`);
- let disconnection = JSON.stringify({
- type: "local_client_disconnect",
- data: {
- totalcount: localClients.length,
- id: 0
- },
- id: -1
- });
- disconnection = encrypt(disconnection, remoteClient, myPkgId, clientPublicKeys);
- if (disconnection === false || disconnection === null) {
- console.log("Error: Failed to encrypt message");
- return;
- }
- console.log(`${TAG_LOCAL} encrypted : ${disconnection}`);
- remoteClient.emit('d2d_message', disconnection);
- }
- });
- } else {
- const TAG_REMOTE = `${TAG}[Remote]`;
+ if (!localClientIps.includes(getIp(ws.handshake.address))) {
const ip = getIp(ws.handshake.address);
- console.log(`${TAG_REMOTE} connected from ${ip}`);
- if (remoteClients[pkgId].indexOf(ws) == -1) {
+ console.log(`${TAG_CLIENT} connected from ${ip}`);
+ if (remoteClients[pkgId].indexOf(ws) === -1) {
remoteClients[pkgId].push(ws);
const index = remoteClients[pkgId].length - 1;
- console.log(`${TAG_REMOTE} pkgId : ${pkgId}`);
- console.log(`${TAG_REMOTE} remote length : ${remoteClients[pkgId].length}`);
- console.log(`${TAG_REMOTE} local length : ${Object.keys(localClients).length}`);
+ console.log(`${TAG_CLIENT} pkgId : ${pkgId}`);
+ console.log(`${TAG_CLIENT} client length : ${remoteClients[pkgId].length}`);
+ console.log(`${TAG_CLIENT} host length : ${Object.keys(sender).length}`);
- let res = JSON.stringify({type: "id", data: index, id: -1});
- res = encrypt(res, ws, pkgId, clientPublicKeys);
- console.log(`${TAG_REMOTE} encrypted : ${res}`);
- if (res === false || res === null) {
- console.log("Error: Failed to encrypt message");
+ const res = JSON.stringify({type: 'id', data: index, id: -1});
+ const encrypted = encrypt(res, ws, pkgId, clientPublicKeys);
+ console.log(`${TAG_CLIENT} encrypted : ${encrypted}`);
+ if (encrypted === false || encrypted === null) {
+ console.log('Error: Failed to encrypt message');
return;
}
- ws.emit('d2d_message', res);
+ ws.emit('d2d_message', encrypted);
+ if (sender[pkgId]) {
+ sender[pkgId].messagePort.sendMessage([{
+ key: pkgId,
+ value: res,
+ }]);
+ }
- console.log(`${TAG_REMOTE}[connection] localClients.length : ${localClients.length}`);
- if (localClients[pkgId] === undefined || Object.keys(localClients).length === 0) {
- console.log(`${TAG_REMOTE} connected : no local-client`);
+ console.log(`${TAG_CLIENT}[connection] sender.length : ${sender.length}`);
+ if (sender[pkgId] === undefined || Object.keys(sender).length === 0) {
+ console.log(`${TAG_CLIENT} connected : waiting for host`);
} else {
- localClients[pkgId].emit('d2d_message', JSON.stringify({type: "new_client", data: index, id: -1}));
+ if (sender[pkgId]) {
+ sender[pkgId].messagePort.sendMessage([{
+ key: pkgId,
+ value: JSON.stringify({type: 'new_client', data: index, id: -1}),
+ }]);
+ }
}
}
ws.on('d2d_message', function(msg) {
break;
}
}
- console.log(`${TAG_REMOTE} #################################`);
- console.log(`${TAG_REMOTE} on d2d message : ${msg}`);
+ console.log(`${TAG_CLIENT} #################################`);
+ console.log(`${TAG_CLIENT} on d2d message : ${msg}`);
msg = decrypt(msg, ws);
- console.log(`${TAG_REMOTE} #################################`);
+ console.log(`${TAG_CLIENT} #################################`);
if (msg === false || msg === null) {
- console.log("Error: Failed to decrypt message");
+ console.log('Error: Failed to decrypt message');
return;
}
- if (localClients[myPkgId]) {
- console.log(`${TAG_REMOTE} decrypted : ${msg}`);
- localClients[myPkgId].emit('d2d_message', msg);
+ if (sender[myPkgId]) {
+ console.log(`${TAG_CLIENT} decrypted : ${msg}`);
+ sender[myPkgId].messagePort.sendMessage([{
+ key: myPkgId,
+ value: msg,
+ }]);
} else {
- console.log(`${TAG_REMOTE} #################################`);
- console.log(`${TAG_REMOTE} localClient is not ready`);
- console.log(`${TAG_REMOTE} #################################`);
+ console.log(`${TAG_CLIENT} #################################`);
+ console.log(`${TAG_CLIENT} localClient is not ready`);
+ console.log(`${TAG_CLIENT} #################################`);
if (localClientMessageQueues[myPkgId] === undefined)
localClientMessageQueues[myPkgId] = [];
localClientMessageQueues[myPkgId].push(msg);
- console.log(`${TAG_REMOTE} localClient is not ready : ${localClientMessageQueues[myPkgId]}`);
+ console.log(`${TAG_CLIENT} localClient is not ready : ${localClientMessageQueues[myPkgId]}`);
}
});
ws.on('disconnect', function(msg) {
- console.log(`${TAG_REMOTE}[close] #################################`);
- console.log(`${TAG_REMOTE}[close] on disconnect event : ${msg}`);
- console.log(`${TAG_REMOTE}[close] #################################`);
+ console.log(`${TAG_CLIENT}[close] #################################`);
+ console.log(`${TAG_CLIENT}[close] on disconnect event : ${msg}`);
+ console.log(`${TAG_CLIENT}[close] #################################`);
let myPkgId = null;
for (let key in remoteClients) {
if (remoteClients[key].indexOf(ws) != -1) {
let index = remoteClients[myPkgId].indexOf(ws);
remoteClients[myPkgId][index] = undefined;
remoteClients[myPkgId].splice(index, 1);
- console.log(`${TAG_REMOTE}[close] localClients[${myPkgId}] : ${localClients[myPkgId]}`);
- if (localClients[myPkgId] !== undefined) {
- console.log(`${TAG_REMOTE}[close] sent remote_client_disconnect`);
- localClients[myPkgId].emit('d2d_message', JSON.stringify({
- type: "remote_client_disconnect",
- data: {
- totalcount: remoteClients[myPkgId].length,
- id: index
- },
- id: -1
- }));
+ console.log(`${TAG_CLIENT}[close] sender[${myPkgId}] : ${sender[myPkgId]}`);
+ if (sender[myPkgId] !== undefined) {
+ console.log(`${TAG_CLIENT}[close] sent remote_client_disconnect to host`);
+ sender[myPkgId].messagePort.sendMessage([{
+ key: pkgId,
+ value: JSON.stringify({
+ type: 'remote_client_disconnect',
+ data: {
+ totalcount: remoteClients[myPkgId].length,
+ id: index
+ },
+ id: -1
+ }),
+ }]);
}
});
}