diff --git a/Environment.js b/Environment.js index bb00891ce..2e75c6265 100644 --- a/Environment.js +++ b/Environment.js @@ -11,9 +11,9 @@ exports.newEnvironment = function () { DEMO_MODE: false, BASE_PATH: basePath, WEB_SERVER_URL: 'localhost', - PLATFORM_WEB_SOCKETS_INTERFACE_PORT: 18041, + PLATFORM_WEB_SOCKETS_INTERFACE_PORT: 16042, + DESKTOP_WEB_SOCKETS_INTERFACE_PORT: 17042, NETWORK_WEB_SOCKETS_INTERFACE_PORT: 18042, - DESKTOP_WEB_SOCKETS_INTERFACE_PORT: 18043, DESKTOP_WEB_SOCKETS_INTERFACE_HOST: 'localhost', PLATFORM_HTTP_INTERFACE_PORT: 34248, DESKTOP_HTTP_INTERFACE_PORT: 34249, diff --git a/Projects/Network/NT/Modules/WebSocketsInterface.js b/Projects/Network/NT/Modules/WebSocketsInterface.js index 16c2593e6..73c490818 100644 --- a/Projects/Network/NT/Modules/WebSocketsInterface.js +++ b/Projects/Network/NT/Modules/WebSocketsInterface.js @@ -135,9 +135,9 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock break } } - if (response.result === 'Ok' && messageHeader.payload.requestType === 'Event') { - broadcastToPeers(messageHeader, caller) - broadcastToClients(messageHeader, caller) + if (response.result === 'Ok' && JSON.parse(messageHeader.payload).requestType === 'Event') { + broadcastToPeers(message, caller) + broadcastToClients(message, caller) } break } @@ -491,7 +491,7 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock } } - function broadcastToPeers(messageHeader, caller) { + function broadcastToPeers(message, caller) { let callerIdToAVoid if (caller.role === 'Network Peer') { callerIdToAVoid = caller.socket.id @@ -499,11 +499,11 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock for (let i = 0; i < thisObject.networkPeers.length; i++) { let networkPeer = thisObject.networkPeers[i] if (networkPeer.socket.id === callerIdToAVoid) { continue } - networkPeer.socket.send(messageHeader) + networkPeer.socket.send(message) } } - function broadcastToClients(messageHeader, caller) { + function broadcastToClients(message, caller) { let callerIdToAVoid if (caller.role === 'Network Client') { callerIdToAVoid = caller.socket.id @@ -511,7 +511,7 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock for (let i = 0; i < thisObject.networkClients.length; i++) { let networkClient = thisObject.networkClients[i] if (networkClient.socket.id === callerIdToAVoid) { continue } - networkClient.socket.send(messageHeader) + networkClient.socket.send(message) } } diff --git a/Projects/Network/SA/Modules/WebSocketsNetworkClient.js b/Projects/Network/SA/Modules/WebSocketsNetworkClient.js index 38fed2cea..b6681fe37 100644 --- a/Projects/Network/SA/Modules/WebSocketsNetworkClient.js +++ b/Projects/Network/SA/Modules/WebSocketsNetworkClient.js @@ -41,7 +41,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb socketClient = new SA.nodeModules.ws('ws://' + thisObject.host + ':' + thisObject.port) await setUpWebsocketClient(callerRole, p2pNetworkNode, onConnectionClosedCallBack) - console.log('Websockets Client Connected to Network Node via Web Sockets .............. Connected to ' + p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port) + console.log('Websockets Client Connected to Network Node via Web Sockets ................ Connected to ' + p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port) thisObject.isConnected = true } @@ -208,7 +208,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb function onConnectionClosed() { if (thisObject.isConnected === true) { - console.log('Websockets Client Connected to Network Node via Web Sockets .............. Disconnected from ' + p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port) + console.log('Websockets Client Connected to Network Node via Web Sockets ............... Disconnected from ' + p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port) } if (onConnectionClosedCallBack !== undefined) { onConnectionClosedCallBack(thisObject.id) @@ -279,7 +279,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb /* We get the function that is going to resolve or reject the promise given. */ - onMenssageFunction = onMessageFunctionsMap.get(response.messageId) + let onMenssageFunction = onMessageFunctionsMap.get(response.messageId) onMessageFunctionsMap.delete(response.messageId) onMenssageFunction(response) } diff --git a/Projects/Social-Trading/NT/Modules/PeerInterface.js b/Projects/Social-Trading/NT/Modules/PeerInterface.js index e25193d5d..30bf6855c 100644 --- a/Projects/Social-Trading/NT/Modules/PeerInterface.js +++ b/Projects/Social-Trading/NT/Modules/PeerInterface.js @@ -8,9 +8,9 @@ exports.newSocialTradingModulesPeerInterface = function newSocialTradingModulesP websockets interface. */ let thisObject = { + messageReceived: messageReceived, initialize: initialize, - finalize: finalize, - run: run + finalize: finalize } return thisObject @@ -22,8 +22,218 @@ exports.newSocialTradingModulesPeerInterface = function newSocialTradingModulesP function initialize() { } + + async function messageReceived(message, userProfile) { + let messageHeader + try { + messageHeader = JSON.parse(message) + } catch (err) { + let response = { + result: 'Error', + message: 'Client Interface message Not Correct JSON Format.' + } + return response + } - function run() { + if (messageHeader.requestType === undefined) { + let response = { + result: 'Error', + message: 'Client Interface requestType Not Provided.' + } + return response + } + if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query') { + let response = { + result: 'Error', + message: 'Client Interface requestType Not Supported.' + } + return response + } + + switch (messageHeader.requestType) { + case 'Event': { + return await eventReceived(messageHeader.eventMessage, userProfile) + } + case 'Query': { + return await queryReceived(messageHeader.queryMessage, userProfile) + } + } + } + + async function eventReceived(eventMessage, userProfile) { + /* + We expect here a JSON string with some or all of the following properties: + + { + "eventId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "eventType": 10, + "emitterUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "emitterBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetBBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "emitterPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "timestamp": 124234234234, + "botAsset": "BTC", + "botExchange": "Binance", + "botEnabled": true + } + */ + + let eventReceived + try { + eventReceived = JSON.parse(eventMessage) + } catch (err) { + let response = { + result: 'Error', + message: 'Client Interface eventMessage Not Correct JSON Format.' + } + return response + } + /* + At the Client Interface, events need to be emitted by the same userProfile that is + connected at the Network Node. + */ + if (eventReceived.emitterUserProfileId !== userProfile.userProfileId) { + let response = { + result: 'Error', + message: 'Client Interface emitterUserProfileId !== userProfileId Connected to Network Node.' + } + return response + } + /* + We will not accept events that don't have an eventId. + */ + if (eventReceived.eventId === undefined) { + let response = { + result: 'Error', + message: 'eventId Not Provided.' + } + return response + } + /* + We will not accept events that have already been processed. + */ + + if (NT.projects.network.globals.memory.maps.EVENTS.get(eventReceived.eventId) !== undefined) { + let response = { + result: 'Error', + message: 'Client Interface Event Already Exists.' + } + return response + } + /* + Here we will process the event and change the state of the Social Graph. + */ + try { + let event = NT.projects.socialTrading.modules.event.newSocialTradingModulesEvent() + event.initialize(eventReceived) + NT.projects.network.globals.memory.maps.EVENTS.set(eventReceived.eventId, event) + NT.projects.network.globals.memory.arrays.EVENTS.push(event) + + let response = { + result: 'Ok', + message: 'Client Interface Event Processed.' + } + return response + + } catch (err) { + /* + Any exception that happens while trying to change the state of the Social Graph, + will be returned to the caller without doing anything else here. + */ + if (err.stack !== undefined) { + console.log('[ERROR] Client Interface -> err.stack = ' + err.stack) + } + let errorMessage = err.message + if (errorMessage === undefined) { errorMessage = err } + let response = { + result: 'Error', + message: 'Client Interface ' + errorMessage + } + return response + } + } + + async function queryReceived(queryMessage, userProfile) { + /* + We expect here a JSON string with some or all of the following properties: + + { + "queryType": 10, + "emitterUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetUserProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "emitterUserProfileHandle": "Luis-Fernando-Molina", + "targetUserProfileHandle": "Luis-Fernando-Molina", + "emitterBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetBBotProfileId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "emitterPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "targetPostHash": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", + "timestamp": 124234234234, + "botAsset": "BTC", + "botExchange": "Binance", + "botEnabled": true, + "initialIndex": 35, + "amountRequested": 50, + "direction": "Past" + } + */ + + let queryReceived + try { + queryReceived = JSON.parse(queryMessage) + } catch (err) { + let response = { + result: 'Error', + message: 'Client Interface queryMessage Not Correct JSON Format.' + } + return response + } + /* + At the Client Interface, queries need to be emitted by the same userProfile that is + connected at the Network Node. + */ + if (queryReceived.emitterUserProfileId !== userProfile.userProfileId) { + let response = { + result: 'Error', + message: 'Client Interface emitterUserProfileId !== userProfileId Connected to Network Node.' + } + return response + } + /* + Here we will process the query. This does not change the state of the Social Graph. + */ + try { + let query = NT.projects.socialTrading.modules.query.newSocialTradingModulesQuery() + query.initialize(queryReceived) + + // console.log((new Date()).toISOString(), '- Client Interface', '- Query Message Received', queryMessage) + + let response = { + result: 'Ok', + message: 'Client Interface Query Processed.', + data: query.execute() + } + + // console.log((new Date()).toISOString(), '- Client Interface', '- Query Response Sent', JSON.stringify(response)) + + return response + + } catch (err) { + /* + Any exception that happens while trying to execute the query. + */ + if (err.stack !== undefined) { + console.log('[ERROR] Client Interface -> err.stack = ' + err.stack) + } + let errorMessage = err.message + if (errorMessage === undefined) { errorMessage = err } + let response = { + result: 'Error', + message: 'Client Interface ' + errorMessage + } + return response + } } } \ No newline at end of file