Merge pull request #2573 from Luis-Fernando-Molina/develop

Contribution: P2P Network: - Broadcasting Events to Peers and Client Implemented
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2021-11-10 09:55:32 -04:00
commit c281ec6094
13 files changed
+129 -80

No files matched your search

+10 -1
View File
@@ -5,8 +5,9 @@ exports.newDesktopApp = function newDesktopApp() {
p2pNetworkClient: undefined,
p2pNetwork: undefined,
p2pNetworkPeers: undefined,
webSocketsClient: undefined,
webSocketsInterface: undefined,
webAppInterface: undefined,
p2pNetworkInterface: undefined,
socialGraph: undefined,
run: run
}
@@ -49,6 +50,14 @@ exports.newDesktopApp = function newDesktopApp() {
}
async function setupServices() {
/*
This is where we will process all the messages comming from our web app.
*/
thisObject.webAppInterface = DK.projects.socialTrading.modules.webAppInterface.newSocialTradingModulesWebAppInterface()
/*
This is where we will process all the events comming from the p2p network.
*/
thisObject.p2pNetworkInterface = DK.projects.socialTrading.modules.p2pNetworkInterface.newSocialTradingModulesP2PNetworkInterface()
/*
This is the Personal Social Graph for the user running this App.
*/
+1 -1
View File
@@ -5,7 +5,7 @@ let UI = {
schemas: { projectSchema: undefined },
environment: undefined,
clientNode: undefined,
running: {}
webApp: undefined
}
let SA = { projects: {} }
+10 -5
View File
@@ -5,6 +5,7 @@ function newWebApp() {
Everything is being coded here until some structure emerges.
*/
let thisObject = {
messageReceived: messageReceived,
initialize: initialize,
finalize: finalize
}
@@ -19,7 +20,7 @@ function newWebApp() {
try {
setupRootObject(UI, 'UI')
setupRootObject(SA, 'SA')
await UI.projects.socialTrading.modules.webSocketsWebClient.initialize()
await UI.projects.socialTrading.modules.webSocketsWebAppClient.initialize()
loadWUserProfileTimeline()
loadWhoToFollow()
setupEventHandlers()
@@ -113,7 +114,7 @@ function newWebApp() {
queryMessage: JSON.stringify(queryMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebClient.sendMessage(
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(query)
)
.then(addToContentDiv)
@@ -183,7 +184,7 @@ function newWebApp() {
queryMessage: JSON.stringify(queryMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebClient.sendMessage(
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(query)
)
.then(addWhoToFollowTable)
@@ -360,7 +361,7 @@ function newWebApp() {
eventMessage: JSON.stringify(eventMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebClient.sendMessage(
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(event)
)
.then(resolve)
@@ -396,7 +397,7 @@ function newWebApp() {
eventMessage: JSON.stringify(eventMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebClient.sendMessage(
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(event)
)
.then(resolve)
@@ -409,4 +410,8 @@ function newWebApp() {
}
}
}
function messageReceived(message) {
window.alert(message)
}
}
+2 -2
View File
@@ -98,8 +98,8 @@ function newWebAppLoader() {
if (downloadedCounter === modulesArray.length) {
setTimeout(() => {
UI.running.webApp = newWebApp()
UI.running.webApp.initialize()
UI.webApp = newWebApp()
UI.webApp.initialize()
}, 500)
}
+2 -2
View File
@@ -28,12 +28,12 @@ exports.newEnvironment = function () {
PATH_TO_MY_WORKSPACES: path.join(basePath, './Platform/My-Workspaces'),
PATH_TO_FONTS: path.join(basePath, './Platform/WebServer/Fonts'),
DESKTOP_APP_SIGNING_ACCOUNT: 'Social-Trading-Desktop-App-1',
DESKTOP_APP_MAX_OUTGOING_PEERS: 2,
DESKTOP_APP_MAX_OUTGOING_PEERS: 1,
MOBILE_APP_SIGNING_ACCOUNT: 'Social-Trading-Mobile-App-1',
SERVER_APP_SIGNING_ACCOUNT: 'Social-Trading-Server-App-1',
PLATFORM_APP_SIGNING_ACCOUNT: 'Algo-Traders-Platform-1',
P2P_NETWORK_NODE_SIGNING_ACCOUNT: 'P2P-Network-Node-1',
P2P_NETWORK_NODE_MAX_INCOMING_CLIENTS: 20,
P2P_NETWORK_NODE_MAX_INCOMING_CLIENTS: 1,
P2P_NETWORK_NODE_MAX_INCOMING_PEERS: 2,
P2P_NETWORK_NODE_MAX_OUTGOING_PEERS: 2
}
@@ -547,11 +547,6 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
let networkClient = thisObject.networkClients[i]
if (networkClient.socket.id === callerIdToAVoid) { continue }
networkClient.socket.send(messageHeader.payload)
.catch(onError)
function onError() {
console.log('[ERROR] Web Sockets Interface -> broadcastToPeers -> Sending Message Failed.')
}
}
}
@@ -112,7 +112,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
let response = JSON.parse(socketMessage.data)
if (response.result !== 'Ok') {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message)
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> response.message = ' + response.message)
reject()
return
}
@@ -123,7 +123,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
We will check that the signature received produces a valid Blockchain Account.
*/
if (called.blockchainAccount === undefined) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> Signature does not produce a valid Blockchain Account.')
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> Signature does not produce a valid Blockchain Account.')
reject()
return
}
@@ -132,7 +132,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
the one we have on record for the user profile of the Network Node we are calling.
*/
if (called.blockchainAccount !== thisObject.p2pNetworkNode.blockchainAccount) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
reject()
return
}
@@ -145,7 +145,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
*/
let hash = web3.eth.accounts.hashMessage(signature.message)
if (hash !== signature.messageHash) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> signature.message Hashed Does Not Match signature.messageHash.')
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> signature.message Hashed Does Not Match signature.messageHash.')
reject()
return
}
@@ -154,7 +154,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
that we have on record, otherwise something is wrong and we should not proceed.
*/
if (signedMessage.calledProfileHandle !== thisObject.p2pNetworkNode.userProfile.userProfileHandle) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
reject()
return
}
@@ -163,7 +163,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
signed message, to avoid man in the middle attacks.
*/
if (signedMessage.callerProfileHandle !== SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).userProfileHandle) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerProfileHandle does not match my own userProfileHandle.')
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> The Network Node callerProfileHandle does not match my own userProfileHandle.')
reject()
return
}
@@ -172,7 +172,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
signed message, also to avoid man in the middle attacks.
*/
if (signedMessage.callerTimestamp !== callerTimestamp) {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> The Network Node callerTimestamp does not match my own callerTimestamp.')
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> The Network Node callerTimestamp does not match my own callerTimestamp.')
reject()
return
}
@@ -206,7 +206,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
let response = JSON.parse(socketMessage.data)
if (response.result !== 'Ok') {
console.log('[ERROR] Web Sockets Client -> stepOneResponse -> response.message = ' + response.message)
console.log('[ERROR] Web Sockets Network Client -> stepOneResponse -> response.message = ' + response.message)
reject()
return
}
@@ -233,18 +233,18 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
function onError(err) {
if (err.message.indexOf('ECONNREFUSED') >= 0) {
console.log('[WARN] Web Sockets Client -> onError -> Nobody home at ' + thisObject.host + ':' + thisObject.port)
console.log('[WARN] Web Sockets Network Client -> onError -> Nobody home at ' + thisObject.host + ':' + thisObject.port)
reject()
return
}
console.log('[ERROR] Web Sockets Client -> onError -> err.message = ' + err.message)
console.log('[ERROR] Web Sockets Client -> onError -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets Network Client -> onError -> err.message = ' + err.message)
console.log('[ERROR] Web Sockets Network Client -> onError -> err.stack = ' + err.stack)
reject()
return
}
} catch (err) {
console.log('[ERROR] Web Sockets Client -> setUpWebSocketClient -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets Network Client -> setUpWebSocketClient -> err.stack = ' + err.stack)
}
}
@@ -257,7 +257,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
function sendSocketMessage(resolve, reject) {
if (thisObject.socket.readyState !== 1) { // 1 means connected and ready.
console.log('[ERROR] Web Sockets Client -> sendMessage -> Cannot send message while connection is closed.')
console.log('[ERROR] Web Sockets Network Client -> sendMessage -> Cannot send message while connection is closed.')
reject('Websockets Connection Not Ready.')
return
}
@@ -274,15 +274,15 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
function onMenssageFunction(response) {
try {
if (response.result === 'Ok') {
if (response.result === 'Ok' || response.result === 'Warning') {
resolve(response.data)
} else {
console.log('[ERROR] Web Sockets Client -> onMenssageFunction -> response.message = ' + response.message)
console.log('[ERROR] Web Sockets Network Client -> onMenssageFunction -> response.message = ' + response.message)
reject(response.message)
}
} catch (err) {
callbackFunction = undefined
console.log('[ERROR] Web Sockets Client -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets Network Client -> err.stack = ' + err.stack)
}
}
}
@@ -290,48 +290,37 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
function onMenssage(socketMessage) {
let response = JSON.parse(socketMessage.data)
let message = JSON.parse(socketMessage.data)
/*
We get the function that is going to resolve or reject the promise given.
*/
let onMenssageFunction = onMessageFunctionsMap.get(response.messageId)
let onMenssageFunction = onMessageFunctionsMap.get(message.messageId)
if (onMenssageFunction !== undefined) {
/*
The message received is a response to a message sent.
*/
onMessageFunctionsMap.delete(response.messageId)
onMenssageFunction(response)
onMessageFunctionsMap.delete(message.messageId)
onMenssageFunction(message)
} else {
/*
The message received is a not response to a message sent.
That means that is a notification received from the Network Node
of an event that happened at some other Client of the Network.
This can only happen when this module is running at an APP like the Desktop App.
*/
let messageHeader
let event
try {
messageHeader = JSON.parse(message)
event = JSON.parse(message.eventMessage)
} catch (err) {
console.log('[ERROR] Web Sockets Client -> onMenssage -> message = ' + message)
console.log('[ERROR] Web Sockets Client -> onMenssage -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets Network Client -> onMenssage -> message = ' + message)
console.log('[ERROR] Web Sockets Network Client -> onMenssage -> err.stack = ' + err.stack)
thisObject.socket.close()
return
}
switch (thisObject.callerRole) {
case 'Network Client': {
/*
This is the use case of a network client receiving a notification of
somethinig that happened at the network that is relevant to itself.
*/
break
}
case 'Network Peer': {
/*
No use cases so far were a Network Peer would send a message through an
incomming websockets connection, without having received a request first.
*/
break
}
}
DK.desktopApp.p2pNetworkInterface.eventReceived(event)
}
}
}
+10 -4
View File
@@ -1606,6 +1606,12 @@
"functionName": "newSocialTradingModulesWebAppInterface",
"fileName": "WebAppInterface.js"
},
{
"name": "P2P Network Interface",
"propertyName": "p2pNetworkInterface",
"functionName": "newSocialTradingModulesP2PNetworkInterface",
"fileName": "P2PNetworkInterface.js"
},
{
"name": "Social Graph",
"propertyName": "socialGraph",
@@ -1618,10 +1624,10 @@
"UI": {
"modules": [
{
"name": "Web Sockets Client",
"propertyName": "webSocketsWebClient",
"functionName": "newSocialTradingModulesWebSocketsWebClient",
"fileName": "WebSocketsWebClient.js"
"name": "Web Sockets WebApp Client",
"propertyName": "webSocketsWebAppClient",
"functionName": "newSocialTradingModulesWebSocketsWebAppClient",
"fileName": "WebSocketsWebAppClient.js"
}
]
}
@@ -0,0 +1,28 @@
exports.newSocialTradingModulesP2PNetworkInterface = function newSocialTradingModulesP2PNetworkInterface() {
/*
This module handles the incoming messages from the P2P Network
that are not responses to requests sent.
This is the case for any kind of events happening at entities followed
by the user running this app, in particular trading events.
*/
let thisObject = {
eventReceived: eventReceived,
initialize: initialize,
finalize: finalize
}
return thisObject
function finalize() {
}
function initialize() {
}
async function eventReceived(event) {
DK.desktopApp.webSocketsInterface.sendToWebApp(JSON.stringify(event))
}
}
@@ -132,7 +132,7 @@ exports.newSocialTradingModulesWebAppInterface = function newSocialTradingModule
let response = {
result: 'Ok',
message: 'Web App Interface Event Processed.',
data: await DK.desktopApp.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
data: await DK.desktopApp.p2pNetworkPeers.sendMessage(JSON.stringify(messageHeader))
}
return response
}
@@ -10,23 +10,18 @@ exports.newDesktopModulesWebSocketsInterface = function newDesktopModulesWebSock
}
let socketServer
let webAppInterface
let webApp
return thisObject
function finalize() {
socketServer = undefined
webAppInterface = undefined
webApp = undefined
}
function initialize() {
let port = JSON.parse(DK.desktopApp.p2pNetworkClient.node.config).webSocketsPort
socketServer = new SA.nodeModules.ws.Server({ port: port })
webAppInterface = DK.projects.socialTrading.modules.webAppInterface.newSocialTradingModulesWebAppInterface()
setUpWebSocketServer()
}
@@ -47,7 +42,7 @@ exports.newDesktopModulesWebSocketsInterface = function newDesktopModulesWebSock
webApp = {
socket: socket
}
console.log('Desktop Web App Connected to Web Sockets Interface ............................. Connected to port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT)
console.log('Desktop Web App Connected to Web Sockets Interface ........................... Connected to port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT)
webApp.socket.on('close', onConnectionClosed)
webApp.socket.on('message', onMenssage)
@@ -67,7 +62,7 @@ exports.newDesktopModulesWebSocketsInterface = function newDesktopModulesWebSock
return
}
await webAppInterface.messageReceived(messageHeader.payload)
await DK.desktopApp.webAppInterface.messageReceived(messageHeader.payload)
.then(sendResponseToWebApp)
.catch(onError)
@@ -111,7 +111,7 @@ exports.newSocialTradingModulesPeerInterface = function newSocialTradingModulesP
if (NT.projects.network.globals.memory.maps.EVENTS.get(eventReceived.eventId) !== undefined) {
let response = {
result: 'Ok',
result: 'Warning',
message: 'Peer Interface Event Already Exists.'
}
return response
@@ -1,4 +1,4 @@
function newSocialTradingModulesWebSocketsWebClient() {
function newSocialTradingModulesWebSocketsWebAppClient() {
let thisObject = {
sendMessage: sendMessage,
@@ -45,12 +45,12 @@ function newSocialTradingModulesWebSocketsWebClient() {
}
function onError(err) {
console.log('[ERROR] Web Sockets Client -> onError -> err.message = ' + err.message)
console.log('[ERROR] Web Sockets Client -> onError -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets WebApp Client -> onError -> err.message = ' + err.message)
console.log('[ERROR] Web Sockets WebApp Client -> onError -> err.stack = ' + err.stack)
}
} catch (err) {
console.log('[ERROR] Web Sockets Client -> setUpWebsocketClient -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets WebApp Client -> setUpWebsocketClient -> err.stack = ' + err.stack)
}
}
}
@@ -62,7 +62,7 @@ function newSocialTradingModulesWebSocketsWebClient() {
function sendSocketMessage(resolve, reject) {
if (socketClient.readyState !== 1) { // 1 means connected and ready.
console.log('[ERROR] Web Sockets Client -> sendMessage -> Cannot send message while connection is closed.')
console.log('[ERROR] Web Sockets WebApp Client -> sendMessage -> Cannot send message while connection is closed.')
reject('Websockets Connection Not Ready.')
return
}
@@ -82,13 +82,13 @@ function newSocialTradingModulesWebSocketsWebClient() {
if (response.result === 'Ok') {
resolve(response.data)
} else {
console.log('[ERROR] Web Sockets Client -> onMenssage -> response.message = ' + response.message)
console.log('[ERROR] Web Sockets WebApp Client -> onMenssage -> response.message = ' + response.message)
reject(response.message)
}
} catch (err) {
callbackFunction = undefined
console.log('[ERROR] Web Sockets Client -> err.stack = ' + err.stack)
console.log('[ERROR] Web Sockets WebApp Client -> err.stack = ' + err.stack)
}
}
}
@@ -96,12 +96,34 @@ function newSocialTradingModulesWebSocketsWebClient() {
function onMenssage(socketMessage) {
let response = JSON.parse(socketMessage.data)
let message = JSON.parse(socketMessage.data)
/*
We get the function that is going to resolve or reject the promise given.
*/
onMenssageFunction = onMessageFunctionsMap.get(response.messageId)
onMessageFunctionsMap.delete(response.messageId)
onMenssageFunction(response)
onMenssageFunction = onMessageFunctionsMap.get(message.messageId)
onMessageFunctionsMap.delete(message.messageId)
if (onMenssageFunction !== undefined) {
/*
The message received is a response to a message sent.
*/
onMenssageFunction(message)
} else {
/*
The message received is a not response to a message sent.
That means that is an event received from the Client App.
*/
let event
try {
event = JSON.parse(message)
} catch (err) {
console.log('[ERROR] Web Sockets WebApp Client -> onMenssage -> message = ' + message)
console.log('[ERROR] Web Sockets WebApp Client -> onMenssage -> err.stack = ' + err.stack)
thisObject.socket.close()
return
}
UI.webApp.messageReceived(JSON.stringify(event))
}
}
}