Merge pull request #2537 from Luis-Fernando-Molina/develop
Contribution: Superalgos P2P Network: Desktop connecting to multiple Network Peers
This commit is contained in:
14 files changed
+487
-178
No files matched your search
+49
-29
@@ -1,10 +1,13 @@
|
|||||||
exports.newDesktopApp = function newDesktopApp() {
|
exports.newDesktopApp = function newDesktopApp() {
|
||||||
|
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
socialGraph: undefined,
|
userProfiles: undefined,
|
||||||
|
p2pNetworkClient: undefined,
|
||||||
p2pNetwork: undefined,
|
p2pNetwork: undefined,
|
||||||
|
p2pNetworkPeers: undefined,
|
||||||
webSocketsClient: undefined,
|
webSocketsClient: undefined,
|
||||||
webSocketsInterface: undefined,
|
webSocketsInterface: undefined,
|
||||||
|
socialGraph: undefined,
|
||||||
run: run
|
run: run
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,37 +16,54 @@ exports.newDesktopApp = function newDesktopApp() {
|
|||||||
return thisObject
|
return thisObject
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
/*
|
|
||||||
This is the Personal Social Graph for the user running this App.
|
|
||||||
*/
|
|
||||||
thisObject.socialGraph = DK.projects.socialTrading.modules.socialGraph.newSocialTradingModulesSocialGraph()
|
|
||||||
await thisObject.socialGraph.initialize()
|
|
||||||
/*
|
|
||||||
We can join now the P2P Network as a client app.
|
|
||||||
*/
|
|
||||||
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
|
|
||||||
await thisObject.p2pNetwork.initialize('Network Client')
|
|
||||||
/*
|
|
||||||
Here we will pick a Network Node from all users profiles available that do have a Network Node running.
|
|
||||||
*/
|
|
||||||
let selectedNetworkNode = thisObject.p2pNetwork.p2pNodesToConnect[0]
|
|
||||||
/*
|
|
||||||
This is the Web Sockets client that interacts with the Superalgos Network.
|
|
||||||
*/
|
|
||||||
thisObject.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient()
|
|
||||||
await thisObject.webSocketsClient.initialize('Network Client', selectedNetworkNode)
|
|
||||||
|
|
||||||
/*
|
setupNetwork()
|
||||||
These are the Network Interfaces by which the Web App interacts with this Desktop Client.
|
setupServices()
|
||||||
*/
|
|
||||||
thisObject.webSocketsInterface = DK.projects.socialTrading.modules.webSocketsInterface.newDesktopModulesWebSocketsInterface()
|
|
||||||
thisObject.webSocketsInterface.initialize()
|
|
||||||
console.log('Desktop Client Web Sockets Interface ....................................... Listening at port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT)
|
|
||||||
|
|
||||||
|
async function setupNetwork() {
|
||||||
|
/*
|
||||||
|
We set up ourselves as a Network Client.
|
||||||
|
*/
|
||||||
|
thisObject.p2pNetworkClient = SA.projects.network.modules.p2pNetworkClient.newNetworkModulesP2PNetworkClient()
|
||||||
|
await thisObject.p2pNetworkClient.initialize()
|
||||||
|
/*
|
||||||
|
We will read all user profiles plugins and get from there our network identity.
|
||||||
|
*/
|
||||||
|
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
|
||||||
|
await thisObject.userProfiles.initialize(global.env.DESKTOP_APP_SIGNING_ACCOUNT, thisObject.p2pNetworkClient)
|
||||||
|
/*
|
||||||
|
We set up the P2P Network.
|
||||||
|
*/
|
||||||
|
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
|
||||||
|
await thisObject.p2pNetwork.initialize('Network Client')
|
||||||
|
/*
|
||||||
|
Set up the connections to network nodes.
|
||||||
|
*/
|
||||||
|
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
|
||||||
|
await thisObject.p2pNetworkPeers.initialize(
|
||||||
|
'Network Client',
|
||||||
|
thisObject.p2pNetworkClient,
|
||||||
|
thisObject.p2pNetwork,
|
||||||
|
global.env.DESKTOP_APP_MAX_OUTGOING_PEERS
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
thisObject.httpInterface = DK.projects.socialTrading.modules.httpInterface.newDesktopModulesHttpInterface()
|
async function setupServices() {
|
||||||
thisObject.httpInterface.initialize()
|
/*
|
||||||
console.log('Desktop Client Http Interface .............................................. Listening at port ' + global.env.DESKTOP_HTTP_INTERFACE_PORT)
|
This is the Personal Social Graph for the user running this App.
|
||||||
|
*/
|
||||||
|
thisObject.socialGraph = DK.projects.socialTrading.modules.socialGraph.newSocialTradingModulesSocialGraph()
|
||||||
|
await thisObject.socialGraph.initialize()
|
||||||
|
/*
|
||||||
|
These are the Network Interfaces by which the Web App interacts with this Desktop Client.
|
||||||
|
*/
|
||||||
|
thisObject.webSocketsInterface = DK.projects.socialTrading.modules.webSocketsInterface.newDesktopModulesWebSocketsInterface()
|
||||||
|
thisObject.webSocketsInterface.initialize()
|
||||||
|
console.log('Desktop Client Web Sockets Interface ....................................... Listening at port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT)
|
||||||
|
|
||||||
|
thisObject.httpInterface = DK.projects.socialTrading.modules.httpInterface.newDesktopModulesHttpInterface()
|
||||||
|
thisObject.httpInterface.initialize()
|
||||||
|
console.log('Desktop Client Http Interface .............................................. Listening at port ' + global.env.DESKTOP_HTTP_INTERFACE_PORT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-2
@@ -11,9 +11,9 @@ exports.newEnvironment = function () {
|
|||||||
DEMO_MODE: false,
|
DEMO_MODE: false,
|
||||||
BASE_PATH: basePath,
|
BASE_PATH: basePath,
|
||||||
WEB_SERVER_URL: 'localhost',
|
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,
|
NETWORK_WEB_SOCKETS_INTERFACE_PORT: 18042,
|
||||||
DESKTOP_WEB_SOCKETS_INTERFACE_PORT: 18043,
|
|
||||||
DESKTOP_WEB_SOCKETS_INTERFACE_HOST: 'localhost',
|
DESKTOP_WEB_SOCKETS_INTERFACE_HOST: 'localhost',
|
||||||
PLATFORM_HTTP_INTERFACE_PORT: 34248,
|
PLATFORM_HTTP_INTERFACE_PORT: 34248,
|
||||||
DESKTOP_HTTP_INTERFACE_PORT: 34249,
|
DESKTOP_HTTP_INTERFACE_PORT: 34249,
|
||||||
@@ -28,6 +28,7 @@ exports.newEnvironment = function () {
|
|||||||
PATH_TO_MY_WORKSPACES: path.join(basePath, './Platform/My-Workspaces'),
|
PATH_TO_MY_WORKSPACES: path.join(basePath, './Platform/My-Workspaces'),
|
||||||
PATH_TO_FONTS: path.join(basePath, './Platform/WebServer/Fonts'),
|
PATH_TO_FONTS: path.join(basePath, './Platform/WebServer/Fonts'),
|
||||||
DESKTOP_APP_SIGNING_ACCOUNT: 'Social-Trading-Desktop-App-1',
|
DESKTOP_APP_SIGNING_ACCOUNT: 'Social-Trading-Desktop-App-1',
|
||||||
|
DESKTOP_APP_MAX_OUTGOING_PEERS: 2,
|
||||||
MOBILE_APP_SIGNING_ACCOUNT: 'Social-Trading-Mobile-App-1',
|
MOBILE_APP_SIGNING_ACCOUNT: 'Social-Trading-Mobile-App-1',
|
||||||
SERVER_APP_SIGNING_ACCOUNT: 'Social-Trading-Server-App-1',
|
SERVER_APP_SIGNING_ACCOUNT: 'Social-Trading-Server-App-1',
|
||||||
PLATFORM_APP_SIGNING_ACCOUNT: 'Algo-Traders-Platform-1',
|
PLATFORM_APP_SIGNING_ACCOUNT: 'Algo-Traders-Platform-1',
|
||||||
|
|||||||
+53
-28
@@ -1,11 +1,13 @@
|
|||||||
exports.newNetworkNode = function newNetworkNode() {
|
exports.newNetworkNode = function newNetworkNode() {
|
||||||
|
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
|
userProfiles: undefined,
|
||||||
|
p2pNetwork: undefined,
|
||||||
|
p2pNetworkPeers: undefined,
|
||||||
|
p2pNetworkNode: undefined,
|
||||||
webSocketsInterface: undefined,
|
webSocketsInterface: undefined,
|
||||||
socialGraphService: undefined,
|
socialGraphService: undefined,
|
||||||
storage: undefined,
|
storage: undefined,
|
||||||
p2pNetwork: undefined,
|
|
||||||
p2pNetworkPeers: undefined,
|
|
||||||
run: run
|
run: run
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,32 +16,55 @@ exports.newNetworkNode = function newNetworkNode() {
|
|||||||
return thisObject
|
return thisObject
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
/*
|
|
||||||
The Social Graph Service is the first and for now, the only service this Network Node provides.
|
|
||||||
*/
|
|
||||||
thisObject.socialGraphService = NT.projects.socialTrading.modules.socialGraph.newNetworkModulesSocialGraph()
|
|
||||||
await thisObject.socialGraphService.initialize()
|
|
||||||
/*
|
|
||||||
The Sotrage deals with persisting the Social Graph.
|
|
||||||
*/
|
|
||||||
thisObject.storage = NT.projects.socialTrading.modules.storage.newSocialTradingModulesStorage()
|
|
||||||
thisObject.storage.initialize()
|
|
||||||
/*
|
|
||||||
Let's discover who is at the p2p network.
|
|
||||||
*/
|
|
||||||
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
|
|
||||||
await thisObject.p2pNetwork.initialize('Network Peer')
|
|
||||||
/*
|
|
||||||
We can join now the P2P Network as a new peer there.
|
|
||||||
*/
|
|
||||||
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
|
|
||||||
await thisObject.p2pNetworkPeers.initialize()
|
|
||||||
/*
|
|
||||||
Other Network Nodes and Client Apps will communicate with this Network Node via it's Websocket Interface.
|
|
||||||
*/
|
|
||||||
thisObject.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface()
|
|
||||||
thisObject.webSocketsInterface.initialize()
|
|
||||||
console.log('Network Node Web Sockets Interface ....................................... Listening at port ' + JSON.parse(NT.networkNode.p2pNetwork.thisNetworkNode.node.config).webSocketsPort)
|
|
||||||
|
|
||||||
|
await setupNetwork()
|
||||||
|
await setupServices()
|
||||||
|
|
||||||
|
async function setupNetwork() {
|
||||||
|
/*
|
||||||
|
We set up ourselves as a Network Node.
|
||||||
|
*/
|
||||||
|
thisObject.p2pNetworkNode = SA.projects.network.modules.p2pNetworkNode.newNetworkModulesP2PNetworkNode()
|
||||||
|
await thisObject.p2pNetworkNode.initialize()
|
||||||
|
/*
|
||||||
|
We will read all user profiles plugins and get from there our network identity.
|
||||||
|
*/
|
||||||
|
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
|
||||||
|
await thisObject.userProfiles.initialize(global.env.P2P_NETWORK_NODE_SIGNING_ACCOUNT, thisObject.p2pNetworkNode)
|
||||||
|
/*
|
||||||
|
Let's discover who is at the p2p network.
|
||||||
|
*/
|
||||||
|
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
|
||||||
|
await thisObject.p2pNetwork.initialize('Network Peer')
|
||||||
|
/*
|
||||||
|
Set up the connections to network nodes.
|
||||||
|
*/
|
||||||
|
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
|
||||||
|
await thisObject.p2pNetworkPeers.initialize(
|
||||||
|
'Network Peer',
|
||||||
|
thisObject.p2pNetworkNode,
|
||||||
|
thisObject.p2pNetwork,
|
||||||
|
global.env.P2P_NETWORK_NODE_MAX_OUTGOING_PEERS
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setupServices() {
|
||||||
|
/*
|
||||||
|
The Social Graph Service is the first and for now, the only service this Network Node provides.
|
||||||
|
*/
|
||||||
|
thisObject.socialGraphService = NT.projects.socialTrading.modules.socialGraph.newNetworkModulesSocialGraph()
|
||||||
|
await thisObject.socialGraphService.initialize()
|
||||||
|
/*
|
||||||
|
The Sotrage deals with persisting the Social Graph.
|
||||||
|
*/
|
||||||
|
thisObject.storage = NT.projects.socialTrading.modules.storage.newSocialTradingModulesStorage()
|
||||||
|
thisObject.storage.initialize()
|
||||||
|
/*
|
||||||
|
Other Network Nodes and Client Apps will communicate with this Network Node via it's Websocket Interface.
|
||||||
|
*/
|
||||||
|
thisObject.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface()
|
||||||
|
thisObject.webSocketsInterface.initialize()
|
||||||
|
console.log('Network Node Web Sockets Interface ....................................... Listening at port ' + JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webSocketsPort)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,9 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
and sending messages to those entities.
|
and sending messages to those entities.
|
||||||
*/
|
*/
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
|
socketServer: undefined,
|
||||||
|
clientInterface: undefined,
|
||||||
|
peerInterface: undefined,
|
||||||
networkClients: undefined,
|
networkClients: undefined,
|
||||||
networkPeers: undefined,
|
networkPeers: undefined,
|
||||||
callersMap: undefined,
|
callersMap: undefined,
|
||||||
@@ -19,10 +22,6 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
finalize: finalize
|
finalize: finalize
|
||||||
}
|
}
|
||||||
|
|
||||||
let socketServer
|
|
||||||
let clientInterface
|
|
||||||
let peerInterface
|
|
||||||
|
|
||||||
let web3 = new SA.nodeModules.web3()
|
let web3 = new SA.nodeModules.web3()
|
||||||
|
|
||||||
return thisObject
|
return thisObject
|
||||||
@@ -32,19 +31,19 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
thisObject.networkPeers = undefined
|
thisObject.networkPeers = undefined
|
||||||
callersMap = undefined
|
callersMap = undefined
|
||||||
|
|
||||||
socketServer = undefined
|
thisObject.socketServer = undefined
|
||||||
clientInterface = undefined
|
thisObject.clientInterface = undefined
|
||||||
peerInterface = undefined
|
thisObject.peerInterface = undefined
|
||||||
|
|
||||||
web3 = undefined
|
web3 = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
let port = JSON.parse(NT.networkNode.p2pNetwork.thisNetworkNode.node.config).webSocketsPort
|
let port = JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webSocketsPort
|
||||||
|
|
||||||
socketServer = new SA.nodeModules.ws.Server({ port: port })
|
thisObject.socketServer = new SA.nodeModules.ws.Server({ port: port })
|
||||||
clientInterface = NT.projects.socialTrading.modules.clientInterface.newSocialTradingModulesClientInterface()
|
thisObject.clientInterface = NT.projects.socialTrading.modules.clientInterface.newSocialTradingModulesClientInterface()
|
||||||
peerInterface = NT.projects.socialTrading.modules.peerInterface.newSocialTradingModulesPeerInterface()
|
thisObject.peerInterface = NT.projects.socialTrading.modules.peerInterface.newSocialTradingModulesPeerInterface()
|
||||||
|
|
||||||
thisObject.networkClients = []
|
thisObject.networkClients = []
|
||||||
thisObject.networkPeers = []
|
thisObject.networkPeers = []
|
||||||
@@ -55,7 +54,7 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
|
|
||||||
function setUpWebSocketServer() {
|
function setUpWebSocketServer() {
|
||||||
try {
|
try {
|
||||||
socketServer.on('connection', onConnectionOpened)
|
thisObject.socketServer.on('connection', onConnectionOpened)
|
||||||
|
|
||||||
function onConnectionOpened(socket)
|
function onConnectionOpened(socket)
|
||||||
/*
|
/*
|
||||||
@@ -65,7 +64,8 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
let caller = {
|
let caller = {
|
||||||
socket: socket,
|
socket: socket,
|
||||||
userProfile: undefined,
|
userProfile: undefined,
|
||||||
role: undefined
|
role: undefined,
|
||||||
|
node: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
caller.socket.id = SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId()
|
caller.socket.id = SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId()
|
||||||
@@ -123,19 +123,19 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
let response
|
let response
|
||||||
switch (caller.role) {
|
switch (caller.role) {
|
||||||
case 'Network Client': {
|
case 'Network Client': {
|
||||||
response = await clientInterface.messageReceived(messageHeader.payload, caller.userProfile)
|
response = await thisObject.clientInterface.messageReceived(messageHeader.payload, caller.userProfile)
|
||||||
response.messageId = messageHeader.messageId
|
response.messageId = messageHeader.messageId
|
||||||
caller.socket.send(JSON.stringify(response))
|
caller.socket.send(JSON.stringify(response))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'Network Peer': {
|
case 'Network Peer': {
|
||||||
response = await peerInterface.messageReceived(messageHeader.payload)
|
response = await thisObject.peerInterface.messageReceived(messageHeader.payload)
|
||||||
response.messageId = messageHeader.messageId
|
response.messageId = messageHeader.messageId
|
||||||
caller.socket.send(JSON.stringify(response))
|
caller.socket.send(JSON.stringify(response))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (response.result === 'Ok' && messageHeader.payload.requestType === 'Event') {
|
if (response.result === 'Ok' && JSON.parse(messageHeader.payload).requestType === 'Event') {
|
||||||
broadcastToPeers(messageHeader, caller)
|
broadcastToPeers(messageHeader, caller)
|
||||||
broadcastToClients(messageHeader, caller)
|
broadcastToClients(messageHeader, caller)
|
||||||
}
|
}
|
||||||
@@ -251,6 +251,32 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
The caller needs to provide it's Node.
|
||||||
|
*/
|
||||||
|
if (messageHeader.callerNode === undefined) {
|
||||||
|
let response = {
|
||||||
|
result: 'Error',
|
||||||
|
message: 'node Not Provided.'
|
||||||
|
}
|
||||||
|
caller.socket.send(JSON.stringify(response))
|
||||||
|
caller.socket.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
The caller's Node needs to be parseable.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
caller.node = JSON.parse(messageHeader.callerNode)
|
||||||
|
} catch (err) {
|
||||||
|
let response = {
|
||||||
|
result: 'Error',
|
||||||
|
message: 'node Not Coorrect JSON Format.'
|
||||||
|
}
|
||||||
|
caller.socket.send(JSON.stringify(response))
|
||||||
|
caller.socket.close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*
|
||||||
The caller needs to provide it's User Profile Handle.
|
The caller needs to provide it's User Profile Handle.
|
||||||
*/
|
*/
|
||||||
if (messageHeader.callerProfileHandle === undefined) {
|
if (messageHeader.callerProfileHandle === undefined) {
|
||||||
@@ -262,7 +288,6 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
caller.socket.close()
|
caller.socket.close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
caller.userProfileHandle = messageHeader.callerProfileHandle
|
caller.userProfileHandle = messageHeader.callerProfileHandle
|
||||||
/*
|
/*
|
||||||
The caller needs to provide a callerTimestamp.
|
The caller needs to provide a callerTimestamp.
|
||||||
@@ -492,14 +517,24 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastToPeers(messageHeader, caller) {
|
function broadcastToPeers(messageHeader, caller) {
|
||||||
|
/*
|
||||||
|
The Boradcast to network peers is not done via
|
||||||
|
the network peers incomming connections, but
|
||||||
|
on the outgoing connections only.
|
||||||
|
*/
|
||||||
let callerIdToAVoid
|
let callerIdToAVoid
|
||||||
if (caller.role === 'Network Peer') {
|
if (caller.role === 'Network Peer') {
|
||||||
callerIdToAVoid = caller.socket.id
|
callerIdToAVoid = caller.node.id
|
||||||
}
|
}
|
||||||
for (let i = 0; i < thisObject.networkPeers.length; i++) {
|
for (let i = 0; i < NT.networkNode.p2pNetworkPeers.peers.length; i++) {
|
||||||
let networkPeer = thisObject.networkPeers[i]
|
let peer = NT.networkNode.p2pNetworkPeers.peers[i]
|
||||||
if (networkPeer.socket.id === callerIdToAVoid) { continue }
|
if (peer.p2pNetworkNode.node.id === callerIdToAVoid) { continue }
|
||||||
networkPeer.socket.send(messageHeader)
|
peer.webSocketsClient.sendMessage(messageHeader.payload)
|
||||||
|
.catch(onError)
|
||||||
|
|
||||||
|
function onError() {
|
||||||
|
console.log('[ERROR] Web Sockets Interface -> broadcastToPeers -> Sending Message Failed.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +546,12 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock
|
|||||||
for (let i = 0; i < thisObject.networkClients.length; i++) {
|
for (let i = 0; i < thisObject.networkClients.length; i++) {
|
||||||
let networkClient = thisObject.networkClients[i]
|
let networkClient = thisObject.networkClients[i]
|
||||||
if (networkClient.socket.id === callerIdToAVoid) { continue }
|
if (networkClient.socket.id === callerIdToAVoid) { continue }
|
||||||
networkClient.socket.send(messageHeader)
|
networkClient.socket.send(messageHeader.payload)
|
||||||
|
.catch(onError)
|
||||||
|
|
||||||
|
function onError() {
|
||||||
|
console.log('[ERROR] Web Sockets Interface -> broadcastToPeers -> Sending Message Failed.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ exports.newNetworkModulesP2PNetwork = function newNetworkModulesP2PNetwork() {
|
|||||||
of this current node to other peers.
|
of this current node to other peers.
|
||||||
*/
|
*/
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
joinTheNetworkAsNetworkPeer: joinTheNetworkAsNetworkPeer,
|
|
||||||
p2pNodesToConnect: undefined,
|
p2pNodesToConnect: undefined,
|
||||||
thisNetworkNode: undefined,
|
|
||||||
/* Framework Functions */
|
/* Framework Functions */
|
||||||
initialize: initialize,
|
initialize: initialize,
|
||||||
finalize: finalize
|
finalize: finalize
|
||||||
@@ -38,18 +36,10 @@ exports.newNetworkModulesP2PNetwork = function newNetworkModulesP2PNetwork() {
|
|||||||
let p2pNetworkNode = SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES[i]
|
let p2pNetworkNode = SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES[i]
|
||||||
if (thisP2PNodeId !== p2pNetworkNode.node.id) {
|
if (thisP2PNodeId !== p2pNetworkNode.node.id) {
|
||||||
thisObject.p2pNodesToConnect.push(p2pNetworkNode)
|
thisObject.p2pNodesToConnect.push(p2pNetworkNode)
|
||||||
} else {
|
|
||||||
thisObject.thisNetworkNode = p2pNetworkNode
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function joinTheNetworkAsNetworkPeer() {
|
|
||||||
/*
|
|
||||||
To join the network we will need to thorugh the list of Network Nodes and pick one to connect to.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
exports.newNetworkModulesP2PNetworkClient = function newNetworkModulesP2PNetworkClient() {
|
||||||
|
/*
|
||||||
|
This module represents the P2P Network Client running at the moment.
|
||||||
|
*/
|
||||||
|
let thisObject = {
|
||||||
|
|
||||||
|
node: undefined,
|
||||||
|
blockchainAccount: undefined,
|
||||||
|
userProfile: undefined,
|
||||||
|
|
||||||
|
/* Framework Functions */
|
||||||
|
initialize: initialize,
|
||||||
|
finalize: finalize
|
||||||
|
}
|
||||||
|
|
||||||
|
return thisObject
|
||||||
|
|
||||||
|
function finalize() {
|
||||||
|
thisObject.node = undefined
|
||||||
|
thisObject.blockchainAccount = undefined
|
||||||
|
thisObject.userProfile = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initialize() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
exports.newNetworkModulesP2PNetworkPeers = function newNetworkModulesP2PNetworkPeers() {
|
exports.newNetworkModulesP2PNetworkPeers = function newNetworkModulesP2PNetworkPeers() {
|
||||||
/*
|
/*
|
||||||
This module holds the P2P Nodes we are coonected to and that are connected to us.
|
This module holds the P2P Nodes we are coonected to.
|
||||||
*/
|
*/
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
outgoingConnectedPeers: undefined,
|
peers: undefined,
|
||||||
|
sendMessage: sendMessage,
|
||||||
|
|
||||||
/* Framework Functions */
|
/* Framework Functions */
|
||||||
initialize: initialize,
|
initialize: initialize,
|
||||||
@@ -16,63 +17,82 @@ exports.newNetworkModulesP2PNetworkPeers = function newNetworkModulesP2PNetworkP
|
|||||||
return thisObject
|
return thisObject
|
||||||
|
|
||||||
function finalize() {
|
function finalize() {
|
||||||
thisObject.outgoingConnectedPeers = undefined
|
thisObject.peers = undefined
|
||||||
clearInterval(intervalIdConnectToPeers)
|
clearInterval(intervalIdConnectToPeers)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initialize() {
|
async function initialize(
|
||||||
|
callerRole,
|
||||||
|
p2pNetworkIdentity,
|
||||||
|
p2pNetwork,
|
||||||
|
maxOutgoingPeers
|
||||||
|
) {
|
||||||
|
|
||||||
thisObject.outgoingConnectedPeers = []
|
thisObject.peers = []
|
||||||
|
|
||||||
connectToPeers()
|
connectToPeers()
|
||||||
intervalIdConnectToPeers = setInterval(connectToPeers, RECONNECT_DELAY);
|
intervalIdConnectToPeers = setInterval(connectToPeers, RECONNECT_DELAY);
|
||||||
|
|
||||||
}
|
async function connectToPeers() {
|
||||||
|
|
||||||
async function connectToPeers() {
|
if (thisObject.peers.length >= maxOutgoingPeers) { return }
|
||||||
|
|
||||||
if (thisObject.outgoingConnectedPeers.count >= global.env.P2P_NETWORK_NODE_MAX_OUTGOING_PEERS) { return }
|
for (let i = 0; i < p2pNetwork.p2pNodesToConnect.length; i++) {
|
||||||
|
if (thisObject.peers.length >= maxOutgoingPeers) { break }
|
||||||
|
|
||||||
for (let i = 0; i < NT.networkNode.p2pNetwork.p2pNodesToConnect.length; i++) {
|
let peer = {
|
||||||
if (thisObject.outgoingConnectedPeers.count >= global.env.P2P_NETWORK_NODE_MAX_OUTGOING_PEERS) { break }
|
p2pNetworkNode: undefined,
|
||||||
let peer = {}
|
webSocketsClient: undefined
|
||||||
peer.p2pNetworkNode = NT.networkNode.p2pNetwork.p2pNodesToConnect[i]
|
}
|
||||||
if (isOutgoingConnectedPeer(peer) === true) { continue }
|
|
||||||
peer.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient()
|
|
||||||
await peer.webSocketsClient.initialize('Network Peer', peer.p2pNetworkNode, onConnectionClosed)
|
|
||||||
.then(addPeer)
|
|
||||||
.catch(onError)
|
|
||||||
|
|
||||||
function addPeer() {
|
peer.p2pNetworkNode = p2pNetwork.p2pNodesToConnect[i]
|
||||||
thisObject.outgoingConnectedPeers.push(peer)
|
if (isConnectedPeer(peer) === true) { continue }
|
||||||
}
|
peer.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient()
|
||||||
|
await peer.webSocketsClient.initialize(callerRole, p2pNetworkIdentity, peer.p2pNetworkNode, onConnectionClosed)
|
||||||
|
.then(addPeer)
|
||||||
|
.catch(onError)
|
||||||
|
|
||||||
function onError(err) {
|
function addPeer() {
|
||||||
if (err !== undefined) {
|
thisObject.peers.push(peer)
|
||||||
console.log('[ERROR] P2P Network Peers -> onError -> While connecting to node -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name + ' -> ' + err.message)
|
}
|
||||||
} else {
|
|
||||||
console.log('[WARN] P2P Network Peers -> onError -> Peer Not Available at the Moment -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name)
|
function onError(err) {
|
||||||
|
if (err !== undefined) {
|
||||||
|
console.log('[ERROR] P2P Network Peers -> onError -> While connecting to node -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name + ' -> ' + err.message)
|
||||||
|
} else {
|
||||||
|
console.log('[WARN] P2P Network Peers -> onError -> Peer Not Available at the Moment -> ' + peer.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + peer.p2pNetworkNode.node.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onConnectionClosed(webSocketsClientId) {
|
||||||
|
for (let i = 0; i < thisObject.peers.length; i++) {
|
||||||
|
let connectedPeer = thisObject.peers[i]
|
||||||
|
if (connectedPeer.webSocketsClient.id === webSocketsClientId) {
|
||||||
|
thisObject.peers.splice(i, 1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onConnectionClosed(webSocketsClientId) {
|
function isConnectedPeer(peer) {
|
||||||
for (let i = 0; i < thisObject.outgoingConnectedPeers.length; i++) {
|
for (let i = 0; i < thisObject.peers.length; i++) {
|
||||||
let connectedPeer = thisObject.outgoingConnectedPeers[i]
|
let connectedPeer = thisObject.peers[i]
|
||||||
if (connectedPeer.webSocketsClient.id === webSocketsClientId) {
|
if (connectedPeer.p2pNetworkNode.node.id === peer.p2pNetworkNode.node.id) {
|
||||||
thisObject.outgoingConnectedPeers.splice(i, 1)
|
return true
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isOutgoingConnectedPeer(peer) {
|
async function sendMessage(message) {
|
||||||
for (let i = 0; i < thisObject.outgoingConnectedPeers.length; i++) {
|
/*
|
||||||
let connectedPeer = thisObject.outgoingConnectedPeers[i]
|
This function will send the message from a random picked network node
|
||||||
if (connectedPeer.p2pNetworkNode.node.id === peer.p2pNetworkNode.node.id) {
|
selected from the array of already connected peers.
|
||||||
return true
|
*/
|
||||||
}
|
let peerIndex = Math.max(Math.round(Math.random() * thisObject.peers.length) - 1, 0)
|
||||||
}
|
let peer = thisObject.peers[peerIndex]
|
||||||
}
|
return await peer.webSocketsClient.sendMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initialize() {
|
async function initialize(signingAccountChildCodeName, p2pNetworkIdentity) {
|
||||||
|
|
||||||
let pluginFileNames = await SA.projects.communityPlugins.utilities.plugins.getPluginFileNames(
|
let pluginFileNames = await SA.projects.communityPlugins.utilities.plugins.getPluginFileNames(
|
||||||
'Governance',
|
'Governance',
|
||||||
@@ -65,7 +65,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles()
|
|||||||
let signatureObject = config.signature
|
let signatureObject = config.signature
|
||||||
let web3 = new SA.nodeModules.web3()
|
let web3 = new SA.nodeModules.web3()
|
||||||
let blockchainAccount = web3.eth.accounts.recover(signatureObject)
|
let blockchainAccount = web3.eth.accounts.recover(signatureObject)
|
||||||
SA.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOKCHAIN_ACCOUNT.set(blockchainAccount, userProfile)
|
SA.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOKCHAIN_ACCOUNT.set(blockchainAccount, userProfile)
|
||||||
/*
|
/*
|
||||||
If the Signing Account is for a P2P node, we will add the node to the array of available nodes at the p2p network.
|
If the Signing Account is for a P2P node, we will add the node to the array of available nodes at the p2p network.
|
||||||
*/
|
*/
|
||||||
@@ -85,12 +85,22 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles()
|
|||||||
}
|
}
|
||||||
if (config.webSocketsPort === undefined) {
|
if (config.webSocketsPort === undefined) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let p2pNetworkNode = SA.projects.network.modules.p2pNetworkNode.newNetworkModulesP2PNetworkNode()
|
let p2pNetworkNode = SA.projects.network.modules.p2pNetworkNode.newNetworkModulesP2PNetworkNode()
|
||||||
p2pNetworkNode.initialize(signingAccount.signingAccountChild, userProfile, blockchainAccount)
|
p2pNetworkNode.initialize(signingAccount.signingAccountChild, userProfile, blockchainAccount)
|
||||||
SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES.push(p2pNetworkNode)
|
SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES.push(p2pNetworkNode)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Now, we will extract the information from the User Profile, specifically of our identity at the p2p network.
|
||||||
|
*/
|
||||||
|
if (
|
||||||
|
signingAccount.signingAccountChild.id === SA.secrets.map.get(signingAccountChildCodeName).signingAccountChildId
|
||||||
|
) {
|
||||||
|
p2pNetworkIdentity.node = signingAccount.signingAccountChild
|
||||||
|
p2pNetworkIdentity.blockchainAccount = blockchainAccount
|
||||||
|
p2pNetworkIdentity.userProfile = userProfile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,19 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
|
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
|
socket: undefined,
|
||||||
isConnected: undefined,
|
isConnected: undefined,
|
||||||
host: undefined,
|
host: undefined,
|
||||||
port: undefined,
|
port: undefined,
|
||||||
|
callerRole: undefined,
|
||||||
|
p2pNetworkNode: undefined,
|
||||||
|
p2pNetworkIdentity: undefined,
|
||||||
|
onConnectionClosedCallBack: undefined,
|
||||||
sendMessage: sendMessage,
|
sendMessage: sendMessage,
|
||||||
initialize: initialize,
|
initialize: initialize,
|
||||||
finalize: finalize
|
finalize: finalize
|
||||||
}
|
}
|
||||||
|
|
||||||
let socketClient
|
|
||||||
|
|
||||||
let web3
|
let web3
|
||||||
let called = {}
|
let called = {}
|
||||||
let onMessageFunctionsMap = new Map()
|
let onMessageFunctionsMap = new Map()
|
||||||
@@ -19,33 +22,44 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
return thisObject
|
return thisObject
|
||||||
|
|
||||||
function finalize() {
|
function finalize() {
|
||||||
socketClient.close()
|
thisObject.socket.close()
|
||||||
socketClient = undefined
|
thisObject.socket = undefined
|
||||||
networkInterface = undefined
|
thisObject.id = undefined
|
||||||
peerInterface = undefined
|
thisObject.isConnected = undefined
|
||||||
|
thisObject.host = undefined
|
||||||
|
thisObject.port = undefined
|
||||||
|
thisObject.callerRole = undefined
|
||||||
|
thisObject.p2pNetworkNode = undefined
|
||||||
|
thisObject.p2pNetworkIdentity = undefined
|
||||||
|
thisObject.onConnectionClosedCallBack = undefined
|
||||||
|
|
||||||
web3 = undefined
|
web3 = undefined
|
||||||
called = undefined
|
called = undefined
|
||||||
onMessageFunctionsMap = undefined
|
onMessageFunctionsMap = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initialize(callerRole, p2pNetworkNode, onConnectionClosedCallBack) {
|
async function initialize(callerRole, p2pNetworkIdentity, p2pNetworkNode, onConnectionClosedCallBack) {
|
||||||
|
|
||||||
|
thisObject.callerRole = callerRole
|
||||||
|
thisObject.p2pNetworkIdentity = p2pNetworkIdentity
|
||||||
|
thisObject.p2pNetworkNode = p2pNetworkNode
|
||||||
|
thisObject.onConnectionClosedCallBack = onConnectionClosedCallBack
|
||||||
|
|
||||||
web3 = new SA.nodeModules.web3()
|
web3 = new SA.nodeModules.web3()
|
||||||
|
|
||||||
thisObject.id = SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId()
|
thisObject.id = SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId()
|
||||||
|
|
||||||
thisObject.host = JSON.parse(p2pNetworkNode.node.config).host
|
thisObject.host = JSON.parse(thisObject.p2pNetworkNode.node.config).host
|
||||||
thisObject.port = JSON.parse(p2pNetworkNode.node.config).webSocketsPort
|
thisObject.port = JSON.parse(thisObject.p2pNetworkNode.node.config).webSocketsPort
|
||||||
|
|
||||||
socketClient = new SA.nodeModules.ws('ws://' + thisObject.host + ':' + thisObject.port)
|
thisObject.socket = new SA.nodeModules.ws('ws://' + thisObject.host + ':' + thisObject.port)
|
||||||
await setUpWebsocketClient(callerRole, p2pNetworkNode, onConnectionClosedCallBack)
|
await setUpWebSocketClient()
|
||||||
|
|
||||||
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 ' + thisObject.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + thisObject.p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port)
|
||||||
thisObject.isConnected = true
|
thisObject.isConnected = true
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setUpWebsocketClient(callerRole, p2pNetworkNode, onConnectionClosedCallBack) {
|
async function setUpWebSocketClient() {
|
||||||
|
|
||||||
return new Promise(connectToNewtwork)
|
return new Promise(connectToNewtwork)
|
||||||
|
|
||||||
@@ -53,9 +67,9 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
socketClient.onopen = () => { onConnectionOpened() }
|
thisObject.socket.onopen = () => { onConnectionOpened() }
|
||||||
socketClient.onclose = () => { onConnectionClosed() }
|
thisObject.socket.onclose = () => { onConnectionClosed() }
|
||||||
socketClient.onerror = err => { onError(err) }
|
thisObject.socket.onerror = err => { onError(err) }
|
||||||
|
|
||||||
function onConnectionOpened() {
|
function onConnectionOpened() {
|
||||||
|
|
||||||
@@ -79,18 +93,19 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
it's own identity, and later we will sign it's own handle
|
it's own identity, and later we will sign it's own handle
|
||||||
to prove ours.
|
to prove ours.
|
||||||
*/
|
*/
|
||||||
socketClient.onmessage = socketMessage => { stepOneResponse(socketMessage) }
|
thisObject.socket.onmessage = socketMessage => { stepOneResponse(socketMessage) }
|
||||||
|
|
||||||
callerTimestamp = (new Date()).valueOf()
|
callerTimestamp = (new Date()).valueOf()
|
||||||
|
|
||||||
let message = {
|
let message = {
|
||||||
messageType: 'Handshake',
|
messageType: 'Handshake',
|
||||||
callerRole: callerRole,
|
callerRole: thisObject.callerRole,
|
||||||
callerProfileHandle: SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).userProfileHandle,
|
callerProfileHandle: SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).userProfileHandle,
|
||||||
callerTimestamp: callerTimestamp,
|
callerTimestamp: callerTimestamp,
|
||||||
|
callerNode: JSON.stringify(thisObject.p2pNetworkIdentity.node),
|
||||||
step: 'One'
|
step: 'One'
|
||||||
}
|
}
|
||||||
socketClient.send(JSON.stringify(message))
|
thisObject.socket.send(JSON.stringify(message))
|
||||||
}
|
}
|
||||||
|
|
||||||
function stepOneResponse(socketMessage) {
|
function stepOneResponse(socketMessage) {
|
||||||
@@ -116,7 +131,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
We will check that the blockchain account taken from the signature matches
|
We will check that the blockchain account taken from the signature matches
|
||||||
the one we have on record for the user profile of the Network Node we are calling.
|
the one we have on record for the user profile of the Network Node we are calling.
|
||||||
*/
|
*/
|
||||||
if (called.blockchainAccount !== p2pNetworkNode.blockchainAccount) {
|
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 Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
|
||||||
reject()
|
reject()
|
||||||
return
|
return
|
||||||
@@ -138,7 +153,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
We will check that the Network Node that responded has the same User Profile Handle
|
We will check that the Network Node that responded has the same User Profile Handle
|
||||||
that we have on record, otherwise something is wrong and we should not proceed.
|
that we have on record, otherwise something is wrong and we should not proceed.
|
||||||
*/
|
*/
|
||||||
if (signedMessage.calledProfileHandle !== p2pNetworkNode.userProfile.userProfileHandle) {
|
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 Client -> stepOneResponse -> The Network Node called does not have the expected Profile Handle.')
|
||||||
reject()
|
reject()
|
||||||
return
|
return
|
||||||
@@ -175,7 +190,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
Here we will sign a message with the Network Node profile
|
Here we will sign a message with the Network Node profile
|
||||||
handle and timestamp to prove our own identity.
|
handle and timestamp to prove our own identity.
|
||||||
*/
|
*/
|
||||||
socketClient.onmessage = socketMessage => { stepTwoResponse(socketMessage) }
|
thisObject.socket.onmessage = socketMessage => { stepTwoResponse(socketMessage) }
|
||||||
|
|
||||||
let signature = web3.eth.accounts.sign(JSON.stringify(signedMessage), SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).privateKey)
|
let signature = web3.eth.accounts.sign(JSON.stringify(signedMessage), SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).privateKey)
|
||||||
|
|
||||||
@@ -184,7 +199,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
signature: JSON.stringify(signature),
|
signature: JSON.stringify(signature),
|
||||||
step: 'Two'
|
step: 'Two'
|
||||||
}
|
}
|
||||||
socketClient.send(JSON.stringify(message))
|
thisObject.socket.send(JSON.stringify(message))
|
||||||
}
|
}
|
||||||
|
|
||||||
function stepTwoResponse(socketMessage) {
|
function stepTwoResponse(socketMessage) {
|
||||||
@@ -200,7 +215,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
Network Node and from now on, all response messages will be received
|
Network Node and from now on, all response messages will be received
|
||||||
at this following function.
|
at this following function.
|
||||||
*/
|
*/
|
||||||
socketClient.onmessage = socketMessage => { onMenssage(socketMessage) }
|
thisObject.socket.onmessage = socketMessage => { onMenssage(socketMessage) }
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,10 +223,10 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
|
|
||||||
function onConnectionClosed() {
|
function onConnectionClosed() {
|
||||||
if (thisObject.isConnected === true) {
|
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 Disconnected from Network Node via Web Sockets ......... Disconnected from ' + thisObject.p2pNetworkNode.userProfile.userProfileHandle + ' -> ' + thisObject.p2pNetworkNode.node.name + ' -> ' + thisObject.host + ':' + thisObject.port)
|
||||||
}
|
}
|
||||||
if (onConnectionClosedCallBack !== undefined) {
|
if (thisObject.onConnectionClosedCallBack !== undefined) {
|
||||||
onConnectionClosedCallBack(thisObject.id)
|
thisObject.onConnectionClosedCallBack(thisObject.id)
|
||||||
}
|
}
|
||||||
thisObject.isConnected = false
|
thisObject.isConnected = false
|
||||||
}
|
}
|
||||||
@@ -229,7 +244,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('[ERROR] Web Sockets Client -> setUpWebsocketClient -> err.stack = ' + err.stack)
|
console.log('[ERROR] Web Sockets Client -> setUpWebSocketClient -> err.stack = ' + err.stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -241,7 +256,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
|
|
||||||
function sendSocketMessage(resolve, reject) {
|
function sendSocketMessage(resolve, reject) {
|
||||||
|
|
||||||
if (socketClient.readyState !== 1) { // 1 means connected and ready.
|
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 Client -> sendMessage -> Cannot send message while connection is closed.')
|
||||||
reject('Websockets Connection Not Ready.')
|
reject('Websockets Connection Not Ready.')
|
||||||
return
|
return
|
||||||
@@ -253,7 +268,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
payload: message
|
payload: message
|
||||||
}
|
}
|
||||||
onMessageFunctionsMap.set(socketMessage.messageId, onMenssageFunction)
|
onMessageFunctionsMap.set(socketMessage.messageId, onMenssageFunction)
|
||||||
socketClient.send(
|
thisObject.socket.send(
|
||||||
JSON.stringify(socketMessage)
|
JSON.stringify(socketMessage)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -279,8 +294,44 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb
|
|||||||
/*
|
/*
|
||||||
We get the function that is going to resolve or reject the promise given.
|
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)
|
if (onMenssageFunction !== undefined) {
|
||||||
|
/*
|
||||||
|
The message received is a response to a message sent.
|
||||||
|
*/
|
||||||
|
onMessageFunctionsMap.delete(response.messageId)
|
||||||
|
onMenssageFunction(response)
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
The message received is a not response to a message sent.
|
||||||
|
*/
|
||||||
|
let messageHeader
|
||||||
|
try {
|
||||||
|
messageHeader = JSON.parse(message)
|
||||||
|
} catch (err) {
|
||||||
|
console.log('[ERROR] Web Sockets Client -> onMenssage -> message = ' + message)
|
||||||
|
console.log('[ERROR] Web Sockets 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1419,6 +1419,12 @@
|
|||||||
"propertyName": "p2pNetworkPeers",
|
"propertyName": "p2pNetworkPeers",
|
||||||
"functionName": "newNetworkModulesP2PNetworkPeers",
|
"functionName": "newNetworkModulesP2PNetworkPeers",
|
||||||
"fileName": "P2PNetworkPeers.js"
|
"fileName": "P2PNetworkPeers.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "P2P Network Client",
|
||||||
|
"propertyName": "p2pNetworkClient",
|
||||||
|
"functionName": "newNetworkModulesP2PNetworkClient",
|
||||||
|
"fileName": "P2PNetworkClient.js"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"utilities": [
|
"utilities": [
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ exports.newSocialTradingModulesSocialGraph = function newSocialTradingModulesSoc
|
|||||||
no need to ask it to a network node.
|
no need to ask it to a network node.
|
||||||
*/
|
*/
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
userProfiles: undefined,
|
|
||||||
initialize: initialize,
|
initialize: initialize,
|
||||||
finalize: finalize
|
finalize: finalize
|
||||||
}
|
}
|
||||||
@@ -26,7 +25,6 @@ exports.newSocialTradingModulesSocialGraph = function newSocialTradingModulesSoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function initialize() {
|
async function initialize() {
|
||||||
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
|
|
||||||
await thisObject.userProfiles.initialize()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,11 +58,11 @@ exports.newSocialTradingModulesWebAppInterface = function newSocialTradingModule
|
|||||||
response = {
|
response = {
|
||||||
result: 'Ok',
|
result: 'Ok',
|
||||||
message: 'Web App Interface Query Processed.',
|
message: 'Web App Interface Query Processed.',
|
||||||
data: await DK.desktopApp.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
|
data: await DK.desktopApp.p2pNetworkPeers.sendMessage(JSON.stringify(messageHeader))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
let events = await DK.desktopApp.webSocketsClient.sendMessage(JSON.stringify(messageHeader))
|
let events = await DK.desktopApp.p2pNetworkPeers.sendMessage(JSON.stringify(messageHeader))
|
||||||
for (let i = 0; i < events.length; i++) {
|
for (let i = 0; i < events.length; i++) {
|
||||||
let event = events[i]
|
let event = events[i]
|
||||||
if (event.eventType === SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST) {
|
if (event.eventType === SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST) {
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ exports.newSocialTradingModulesPeerInterface = function newSocialTradingModulesP
|
|||||||
websockets interface.
|
websockets interface.
|
||||||
*/
|
*/
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
|
messageReceived: messageReceived,
|
||||||
initialize: initialize,
|
initialize: initialize,
|
||||||
finalize: finalize,
|
finalize: finalize
|
||||||
run: run
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return thisObject
|
return thisObject
|
||||||
@@ -22,8 +22,130 @@ exports.newSocialTradingModulesPeerInterface = function newSocialTradingModulesP
|
|||||||
function initialize() {
|
function initialize() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function messageReceived(message) {
|
||||||
|
let messageHeader
|
||||||
|
try {
|
||||||
|
messageHeader = JSON.parse(message)
|
||||||
|
} catch (err) {
|
||||||
|
let response = {
|
||||||
|
result: 'Error',
|
||||||
|
message: 'Peer Interface message Not Correct JSON Format.'
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
function run() {
|
if (messageHeader.requestType === undefined) {
|
||||||
|
let response = {
|
||||||
|
result: 'Error',
|
||||||
|
message: 'Peer Interface requestType Not Provided.'
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messageHeader.requestType !== 'Event' && messageHeader.requestType !== 'Query') {
|
||||||
|
let response = {
|
||||||
|
result: 'Error',
|
||||||
|
message: 'Peer Interface requestType Not Supported.'
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (messageHeader.requestType) {
|
||||||
|
case 'Event': {
|
||||||
|
return await eventReceived(messageHeader.eventMessage)
|
||||||
|
}
|
||||||
|
case 'Query': {
|
||||||
|
let response = {
|
||||||
|
result: 'Error',
|
||||||
|
message: 'Peer Interface requestType Query Not Supported.'
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function eventReceived(eventMessage) {
|
||||||
|
/*
|
||||||
|
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: 'Peer Interface eventMessage Not Correct JSON Format.'
|
||||||
|
}
|
||||||
|
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: 'Ok',
|
||||||
|
message: 'Peer 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: 'Peer 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] Peer Interface -> err.stack = ' + err.stack)
|
||||||
|
}
|
||||||
|
let errorMessage = err.message
|
||||||
|
if (errorMessage === undefined) { errorMessage = err }
|
||||||
|
let response = {
|
||||||
|
result: 'Error',
|
||||||
|
message: 'Peer Interface ' + errorMessage
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ exports.newNetworkModulesSocialGraph = function newNetworkModulesSocialGraph() {
|
|||||||
their posts.
|
their posts.
|
||||||
*/
|
*/
|
||||||
let thisObject = {
|
let thisObject = {
|
||||||
userProfiles: undefined,
|
|
||||||
/* Framework Functions */
|
/* Framework Functions */
|
||||||
initialize: initialize,
|
initialize: initialize,
|
||||||
finalize: finalize
|
finalize: finalize
|
||||||
@@ -22,7 +22,6 @@ exports.newNetworkModulesSocialGraph = function newNetworkModulesSocialGraph() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function initialize() {
|
async function initialize() {
|
||||||
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
|
|
||||||
await thisObject.userProfiles.initialize()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user