Merge pull request #1617 from Luis-Fernando-Molina/develop
Contribution: Superalgos Network: Websockets Implemented
This commit is contained in:
15 files changed
+511
-165
No files matched your search
+1
-1
@@ -163,7 +163,7 @@ try {
|
||||
WEB_SOCKETS_INTERFACE = WEB_SOCKETS_INTERFACE.newWebSocketsInterface()
|
||||
WEB_SOCKETS_INTERFACE.initialize()
|
||||
WEB_SOCKETS_INTERFACE.run()
|
||||
console.log('Web Sockets Interface ....................................... Listening at port ' + global.env.WEB_SOCKETS_INTERFACE_PORT)
|
||||
console.log('Web Sockets Interface ....................................... Listening at port ' + global.env.CLIENT_WEB_SOCKETS_INTERFACE_PORT)
|
||||
|
||||
HTTP_INTERFACE = HTTP_INTERFACE.newHttpInterface()
|
||||
HTTP_INTERFACE.initialize()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
const WEB_SOCKET = require('ws')
|
||||
let socketServer
|
||||
let port = global.env.WEB_SOCKETS_INTERFACE_PORT
|
||||
let port = global.env.CLIENT_WEB_SOCKETS_INTERFACE_PORT
|
||||
|
||||
return thisObject
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ exports.newEnvironment = function () {
|
||||
|
||||
let thisObject = {
|
||||
WEB_SERVER_URL: 'localhost',
|
||||
WEB_SOCKETS_INTERFACE_PORT: 18041,
|
||||
CLIENT_WEB_SOCKETS_INTERFACE_PORT: 18041,
|
||||
HTTP_INTERFACE_PORT: 34248,
|
||||
PATH_TO_TASK_SERVER: './TaskServer',
|
||||
PATH_TO_DATA_STORAGE: './Data-Storage',
|
||||
|
||||
+13
-12
@@ -2,20 +2,21 @@ exports.newEnvironment = function () {
|
||||
|
||||
let thisObject = {
|
||||
WEB_SERVER_URL: 'localhost',
|
||||
WEB_SOCKETS_INTERFACE_PORT: 18041,
|
||||
CLIENT_WEB_SOCKETS_INTERFACE_PORT: 18041,
|
||||
NETWORK_WEB_SOCKETS_INTERFACE_PORT: 18042,
|
||||
HTTP_INTERFACE_PORT: 34248,
|
||||
PATH_TO_TASK_SERVER: '../TaskServer',
|
||||
PATH_TO_DATA_STORAGE: '../Data-Storage',
|
||||
PATH_TO_PROJECTS: '../Projects',
|
||||
PATH_TO_LOG_FILES: '../Log-Files',
|
||||
PATH_TO_TASK_SERVER: './TaskServer',
|
||||
PATH_TO_DATA_STORAGE: './Data-Storage',
|
||||
PATH_TO_PROJECTS: './Projects',
|
||||
PATH_TO_LOG_FILES: './Log-Files',
|
||||
PATH_TO_PROJECTS_REQUIRED: './Projects',
|
||||
PATH_TO_PROJECT_SCHEMA: '../Projects/ProjectsSchema.json',
|
||||
PATH_TO_UI: '../UI',
|
||||
PATH_TO_DATA_FILES: '../UI/Data-Files/src',
|
||||
PATH_TO_CLIENT: '../Client/',
|
||||
PATH_TO_DEFAULT_WORKSPACE: '../Projects/Foundations/Plugins/Workspaces',
|
||||
PATH_TO_MY_WORKSPACES: '../My-Workspaces',
|
||||
PATH_TO_FONTS: '../Client/WebServer/Fonts'
|
||||
PATH_TO_PROJECT_SCHEMA: './Projects/ProjectsSchema.json',
|
||||
PATH_TO_UI: './UI',
|
||||
PATH_TO_DATA_FILES: './UI/Data-Files/src',
|
||||
PATH_TO_CLIENT: './Client/',
|
||||
PATH_TO_DEFAULT_WORKSPACE: './Projects/Foundations/Plugins/Workspaces',
|
||||
PATH_TO_MY_WORKSPACES: './My-Workspaces',
|
||||
PATH_TO_FONTS: './Client/WebServer/Fonts'
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
+17
-46
@@ -1,53 +1,24 @@
|
||||
/*
|
||||
The Superalgos Network offers 3 types of services:
|
||||
exports.newNetworkNode = function newNetworkNode() {
|
||||
|
||||
* Social Graph Service
|
||||
* Search Index Service
|
||||
* Private Message Service
|
||||
|
||||
Users can decide which services to run at their node.
|
||||
let thisObject = {
|
||||
run: run
|
||||
}
|
||||
|
||||
This module is the starting point of the Network Node.
|
||||
return thisObject
|
||||
|
||||
*/
|
||||
function run() {
|
||||
/*
|
||||
Let's start the Network Interfaces
|
||||
*/
|
||||
NT.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface()
|
||||
NT.webSocketsInterface.initialize()
|
||||
|
||||
/*
|
||||
The NT object is accesible everywhere at the Superalgos Network.
|
||||
It provides access to all modules built for this Network.
|
||||
*/
|
||||
global.NT = {}
|
||||
/*
|
||||
The SA object is accesible everywhere at the Superalgos Network.
|
||||
It provides access to all modules built for Superalgos in general.
|
||||
*/
|
||||
global.SA = {}
|
||||
/* Load Environment Variables */
|
||||
let ENVIRONMENT = require('../EnvironmentForDebug.js');
|
||||
let ENVIRONMENT_MODULE = ENVIRONMENT.newEnvironment()
|
||||
global.env = ENVIRONMENT_MODULE
|
||||
/*
|
||||
First thing is to load the project schema file.
|
||||
*/
|
||||
global.PROJECTS_SCHEMA = require(global.env.PATH_TO_PROJECT_SCHEMA)
|
||||
/*
|
||||
Setting up the modules that will be available for the Servers Running inside this Client
|
||||
*/
|
||||
let MULTI_PROJECT = require('../MultiProject.js');
|
||||
let MULTI_PROJECT_MODULE = MULTI_PROJECT.newMultiProject()
|
||||
MULTI_PROJECT_MODULE.initialize(NT, 'NT')
|
||||
MULTI_PROJECT_MODULE.initialize(SA, 'SA')
|
||||
/*
|
||||
Setting up external dependencies.
|
||||
*/
|
||||
SA.nodeModules = {
|
||||
fs: require('fs'),
|
||||
nodeFetch: require('node-fetch'),
|
||||
web3: require('web3')
|
||||
}
|
||||
start()
|
||||
|
||||
start()
|
||||
async function start() {
|
||||
let socialGraphService = NT.projects.network.modules.socialGraph.newSocialGraph()
|
||||
await socialGraphService.initialize()
|
||||
}
|
||||
|
||||
async function start() {
|
||||
let socialGraphService = NT.projects.network.modules.socialGraph.newSocialGraph()
|
||||
await socialGraphService.initialize()
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
exports.newClientInterface = function newClientInterface() {
|
||||
/*
|
||||
This module represents the Interface the Network Node have
|
||||
with Network Clients connected to it. There are two things
|
||||
Network Clients can do with this Network Node:
|
||||
|
||||
* Send an Event that happened at the Network Client to the Network.
|
||||
* Make a Query to the Network Node for info needed at the Network Client.
|
||||
*/
|
||||
let thisObject = {
|
||||
eventReceived: eventReceived,
|
||||
queryReceived: queryReceived,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize() {
|
||||
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
|
||||
}
|
||||
|
||||
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 = JSON.parse(eventMessage)
|
||||
if (NT.projects.network.globals.memory.maps.EVENTS.get(eventReceived.eventId) !== undefined) {
|
||||
throw ('Event Already Exists.')
|
||||
}
|
||||
|
||||
let event = NT.projects.network.modules.event.newNetworkModulesEvent()
|
||||
event.initialize(eventReceived)
|
||||
NT.projects.network.globals.memory.maps.EVENTS.set(eventReceived.eventId, event)
|
||||
}
|
||||
|
||||
function queryReceived(queryMessage) {
|
||||
/*
|
||||
We expect here a JSON string with some or all of the following properties:
|
||||
|
||||
{
|
||||
"equeryId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
|
||||
"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 = JSON.parse(queryMessage)
|
||||
let query = NT.projects.network.modules.queriesQuery.newNetworkModulesQuery()
|
||||
query.initialize(queryReceived)
|
||||
return query.execute()
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,14 @@ exports.newNetworkGlobalsMemory = function () {
|
||||
*/
|
||||
let thisObject = {
|
||||
maps: {
|
||||
USER_PROFILES_BY_ID: new Map(), // Here we will store the user profiles by User Profile Id.
|
||||
USER_PROFILES_BY_HANDLE: new Map(), // Here we will store the user profiles by User Profile Handle.
|
||||
EVENTS: new Map(), // This is the registry of all events received that prevents processing them more than once.
|
||||
USER_PROFILES_BY_ID: new Map(), // Here we will store the user profiles by User Profile Id.
|
||||
USER_PROFILES_BY_HANDLE: new Map(), // Here we will store the user profiles by User Profile Handle.
|
||||
USER_PROFILES_BY_BLOCHAIN_ACCOUNT: new Map(), // Here we will store the user profiles by Blockchain Account.
|
||||
EVENTS: new Map(), // This is the registry of all events received that prevents processing them more than once.
|
||||
},
|
||||
arrays: {
|
||||
NETWORK_CLIENTS: [], // These are the Network Clients connected to this Network Node ordered by Ranking.
|
||||
NETWORK_PEERS: [], // These are the Network Peers connected to this Network Node ordered by Ranking.
|
||||
NETWORK_CLIENTS: [], // These are the Network Clients connected to this Network Node ordered by Ranking.
|
||||
NETWORK_PEERS: [], // These are the Network Peers connected to this Network Node ordered by Ranking.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ exports.newBootstrap = function newBootstrap() {
|
||||
let config = JSON.parse(userProfilePlugin.config)
|
||||
let signatureObject = config.signature
|
||||
let web3 = new SA.nodeModules.web3()
|
||||
let bloackchainAddress = web3.eth.accounts.recover(signatureObject)
|
||||
let blockchainAccount = web3.eth.accounts.recover(signatureObject)
|
||||
let ranking = 0 // TODO: read the blockchain balance and transactions from the Treasury Account to calculate the profile ranking.
|
||||
let userProfileId = userProfilePlugin.id
|
||||
let userHandle = config.signature.message
|
||||
@@ -45,12 +45,13 @@ exports.newBootstrap = function newBootstrap() {
|
||||
userProfile.initialize(
|
||||
userProfileId,
|
||||
userHandle,
|
||||
bloackchainAddress,
|
||||
blockchainAccount,
|
||||
ranking
|
||||
)
|
||||
|
||||
NT.projects.network.globals.memory.maps.USER_PROFILES_BY_ID.set(userProfileId, userProfile)
|
||||
NT.projects.network.globals.memory.maps.USER_PROFILES_BY_HANDLE.set(userHandle, userProfile)
|
||||
NT.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOCHAIN_ACCOUNT.set(blockchainAccount, userProfile)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
exports.newNetworkModulesClientInterface = function newNetworkModulesClientInterface() {
|
||||
/*
|
||||
This module represents the Interface the Network Node have
|
||||
with Network Clients connected to it. There are two things
|
||||
Network Clients can do with this Network Node:
|
||||
|
||||
* Send an Event that happened at the Network Client to the Network.
|
||||
* Make a Query to the Network Node for info needed at the Network Client.
|
||||
*/
|
||||
let thisObject = {
|
||||
messageReceived: messageReceived,
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize() {
|
||||
|
||||
}
|
||||
|
||||
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 Coorrect JSON Format.'
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
if (messageHeader.messageType === undefined) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'Client Interface messageType Not Provided.'
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
if (messageHeader.messageType !== 'Event' && messageHeader.messageType !== 'Query') {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'Client Interface messageType Not Supported.'
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
switch (messageHeader.messageType) {
|
||||
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 Coorrect JSON Format.'
|
||||
}
|
||||
return response
|
||||
}
|
||||
/*
|
||||
At the Client Interface, events need to be emmitted 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 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.network.modules.event.newNetworkModulesEvent()
|
||||
event.initialize(eventReceived)
|
||||
NT.projects.network.globals.memory.maps.EVENTS.set(eventReceived.eventId, 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.
|
||||
*/
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'Client Interface ' + err.message
|
||||
}
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
async function queryReceived(queryMessage, userProfile) {
|
||||
/*
|
||||
We expect here a JSON string with some or all of the following properties:
|
||||
|
||||
{
|
||||
"equeryId": "a8de78f0-c3e4-4a2a-b7e8-f659073969db",
|
||||
"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 Coorrect JSON Format.'
|
||||
}
|
||||
return response
|
||||
}
|
||||
/*
|
||||
At the Client Interface, queries need to be emmitted 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.network.modules.queriesQuery.newNetworkModulesQuery()
|
||||
query.initialize(queryReceived)
|
||||
return query.execute()
|
||||
|
||||
} catch (err) {
|
||||
/*
|
||||
Any exception that happens while trying to execute the query.
|
||||
*/
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'Client Interface ' + err.message
|
||||
}
|
||||
return response
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
exports.newPeerInterface = function newPeerInterface() {
|
||||
exports.newNetworkModulesPeerInterface = function newNetworkModulesPeerInterface() {
|
||||
|
||||
let thisObject = {
|
||||
initialize: initialize,
|
||||
@@ -0,0 +1,173 @@
|
||||
exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSocketsInterface() {
|
||||
|
||||
let thisObject = {
|
||||
initialize: initialize,
|
||||
finalize: finalize
|
||||
}
|
||||
|
||||
let socketServer
|
||||
let clientInterface
|
||||
let peerInterface
|
||||
|
||||
return thisObject
|
||||
|
||||
function finalize() {
|
||||
socketServer = undefined
|
||||
clientInterface = undefined
|
||||
peerInterface = undefined
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
socketServer = new SA.nodeModules.ws.Server({ port: global.env.NETWORK_WEB_SOCKETS_INTERFACE_PORT })
|
||||
clientInterface = NT.projects.network.modules.clientInterface.newNetworkModulesClientInterface()
|
||||
peerInterface = NT.projects.network.modules.peerInterface.newNetworkModulesPeerInterface()
|
||||
|
||||
setUpWebSocketServer()
|
||||
}
|
||||
|
||||
function setUpWebSocketServer() {
|
||||
try {
|
||||
socketServer.on('connection', onConnection)
|
||||
|
||||
function onConnection(socket) {
|
||||
let caller = {}
|
||||
socket.on('message', onMenssage)
|
||||
|
||||
async function onMenssage(message) {
|
||||
try {
|
||||
let messageHeader
|
||||
try {
|
||||
messageHeader = JSON.parse(message)
|
||||
} catch (err) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'messageHeader Not Coorrect JSON Format.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
/*
|
||||
We will run some validations.
|
||||
*/
|
||||
if (messageHeader.messageType === undefined) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'messageType Not Provided.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
|
||||
switch (messageHeader.messageType) {
|
||||
case "Handshake": {
|
||||
handshakeProducedure(socket, caller, messageHeader)
|
||||
break
|
||||
}
|
||||
case "Request": {
|
||||
|
||||
if (caller.userProfile === undefined) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'Handshake Not Done Yet.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
|
||||
switch (caller.role) {
|
||||
case 'Network Client': {
|
||||
let response = await clientInterface.messageReceived(messageHeader.payload, caller.userProfile)
|
||||
socket.send(JSON.stringify(response))
|
||||
break
|
||||
}
|
||||
case 'Network Peer': {
|
||||
let response = await peerInterface.messageReceived(messageHeader.payload)
|
||||
socket.send(JSON.stringify(response))
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Network -> Web Sockets Interface -> run -> setUpWebSocketServer -> err.stack = ' + err.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handshakeProducedure(socket, caller, messageHeader) {
|
||||
/*
|
||||
The caller needs to identify itself as either a Network Client or Peer.
|
||||
*/
|
||||
if (messageHeader.callerRole === undefined) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'callerRole Not Provided.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
|
||||
if (messageHeader.callerRole !== 'Network Client' && messageHeader.callerRole !== 'Network Peer') {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'callerRole Not Supported.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
|
||||
caller.role = messageHeader.callerRole
|
||||
/*
|
||||
We will identify the caller by the signature at the message.
|
||||
*/
|
||||
if (messageHeader.signature === undefined) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'signature Not Provided.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
|
||||
let web3 = new SA.nodeModules.web3()
|
||||
let blockchainAccount = web3.eth.accounts.recover(messageHeader.signature)
|
||||
|
||||
if (caller.blockchainAccount === undefined) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'Bad signature.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
/*
|
||||
The signature gives us the blockchain account, and the account the user profile.
|
||||
*/
|
||||
let userProfile = NT.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOCHAIN_ACCOUNT.set(blockchainAccount)
|
||||
|
||||
if (userProfile === undefined) {
|
||||
let response = {
|
||||
result: 'Error',
|
||||
message: 'userProfile Not Found.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
return
|
||||
}
|
||||
/*
|
||||
We will remember the user profile behind this caller.
|
||||
*/
|
||||
caller.userProfile = userProfile
|
||||
|
||||
let response = {
|
||||
result: 'Ok',
|
||||
message: 'Handshake Successful.'
|
||||
}
|
||||
socket.send(JSON.stringify(response))
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.log('[ERROR] Network -> Web Sockets Interface -> run -> setUpWebSocketServer -> err.stack = ' + err.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1370,6 +1370,24 @@
|
||||
"propertyName": "event",
|
||||
"functionName": "newNetworkModulesEvent",
|
||||
"fileName": "Event.js"
|
||||
},
|
||||
{
|
||||
"name": "Client Interface",
|
||||
"propertyName": "clientInterface",
|
||||
"functionName": "newNetworkModulesClientInterface",
|
||||
"fileName": "ClientInterface.js"
|
||||
},
|
||||
{
|
||||
"name": "Peer Interface",
|
||||
"propertyName": "peerInterface",
|
||||
"functionName": "newNetworkModulesPeerInterface",
|
||||
"fileName": "PeerInterface.js"
|
||||
},
|
||||
{
|
||||
"name": "Web Sockets Interface",
|
||||
"propertyName": "webSocketsInterface",
|
||||
"functionName": "newNetworkModulesWebSocketsInterface",
|
||||
"fileName": "WebSocketsInterface.js"
|
||||
}
|
||||
],
|
||||
"utilities": [
|
||||
|
||||
Generated
+15
-8
@@ -977,6 +977,18 @@
|
||||
"servify": "^0.1.12",
|
||||
"ws": "^3.0.0",
|
||||
"xhr-request-promise": "^0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0",
|
||||
"safe-buffer": "~5.1.0",
|
||||
"ultron": "~1.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ethereum-bloom-filters": {
|
||||
@@ -2945,14 +2957,9 @@
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0",
|
||||
"safe-buffer": "~5.1.0",
|
||||
"ultron": "~1.1.0"
|
||||
}
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.1.tgz",
|
||||
"integrity": "sha512-XkgWpJU3sHU7gX8f13NqTn6KQ85bd1WU7noBHTT8fSohx7OS1TPY8k+cyRPCzFkia7C4mM229yeHr1qK9sM4JQ=="
|
||||
},
|
||||
"xhr": {
|
||||
"version": "2.6.0",
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.6.1",
|
||||
"web3": "^1.5.2"
|
||||
"web3": "^1.5.2",
|
||||
"ws": "^8.2.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
The Superalgos Network offers 3 types of services:
|
||||
|
||||
* Social Graph Service
|
||||
* Search Index Service
|
||||
* Private Message Service
|
||||
|
||||
Users can decide which services to run at their node.(TODO)
|
||||
|
||||
This module is the starting point of the Network Node.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
The NT object is accesible everywhere at the Superalgos Network.
|
||||
It provides access to all modules built for this Network.
|
||||
*/
|
||||
global.NT = {}
|
||||
/*
|
||||
The SA object is accesible everywhere at the Superalgos Network.
|
||||
It provides access to all modules built for Superalgos in general.
|
||||
*/
|
||||
global.SA = {}
|
||||
/* Load Environment Variables */
|
||||
let ENVIRONMENT = require('./EnvironmentForDebug.js');
|
||||
let ENVIRONMENT_MODULE = ENVIRONMENT.newEnvironment()
|
||||
global.env = ENVIRONMENT_MODULE
|
||||
/*
|
||||
First thing is to load the project schema file.
|
||||
*/
|
||||
global.PROJECTS_SCHEMA = require(global.env.PATH_TO_PROJECT_SCHEMA)
|
||||
/*
|
||||
Setting up the modules that will be available, defined at the Project Schema file.
|
||||
*/
|
||||
let MULTI_PROJECT = require('./MultiProject.js');
|
||||
let MULTI_PROJECT_MODULE = MULTI_PROJECT.newMultiProject()
|
||||
MULTI_PROJECT_MODULE.initialize(NT, 'NT')
|
||||
MULTI_PROJECT_MODULE.initialize(SA, 'SA')
|
||||
/*
|
||||
Setting up external dependencies.
|
||||
*/
|
||||
SA.nodeModules = {
|
||||
fs: require('fs'),
|
||||
nodeFetch: require('node-fetch'),
|
||||
web3: require('web3'),
|
||||
ws: require('ws')
|
||||
}
|
||||
|
||||
NT.app = require('./Network/NetwokNode.js').newNetworkNode()
|
||||
NT.app.run()
|
||||
|
||||
console.log('Superalgos Network is Running.')
|
||||
Reference in new issue
Block a user