163 lines
7.0 KiB
JavaScript
163 lines
7.0 KiB
JavaScript
const fs = require('fs');
|
|
const url = require('url');
|
|
const http = require('http');
|
|
const https = require('https');
|
|
const express = require('express');
|
|
const { createWebSocketServer, createWebSocketClient } = require('./basic/websocketTools.js')
|
|
module.exports = function(s,config,lang,app,io){
|
|
//setup Master for childNodes
|
|
if(
|
|
config.childNodes.enabled === true &&
|
|
config.childNodes.mode === 'master'
|
|
){
|
|
const {
|
|
getIpAddress,
|
|
initiateDataConnection,
|
|
initiateVideoTransferConnection,
|
|
onWebSocketDataFromChildNode,
|
|
onDataConnectionDisconnect,
|
|
initiateVideoWriteFromChildNode,
|
|
initiateTimelapseFrameWriteFromChildNode,
|
|
} = require('./childNode/utils.js')(s,config,lang,app,io)
|
|
s.childNodes = {};
|
|
const childNodesConnectionIndex = {};
|
|
const childNodeHTTP = express();
|
|
const childNodeServer = http.createServer(app);
|
|
const childNodeWebsocket = createWebSocketServer();
|
|
const childNodeFileRelay = createWebSocketServer();
|
|
childNodeServer.on('upgrade', function upgrade(request, socket, head) {
|
|
const pathname = url.parse(request.url).pathname;
|
|
if (pathname === '/childNode') {
|
|
childNodeWebsocket.handleUpgrade(request, socket, head, function done(ws) {
|
|
childNodeWebsocket.emit('connection', ws, request)
|
|
})
|
|
} else if (pathname === '/childNodeFileRelay') {
|
|
childNodeFileRelay.handleUpgrade(request, socket, head, function done(ws) {
|
|
childNodeFileRelay.emit('connection', ws, request)
|
|
})
|
|
} else {
|
|
socket.destroy();
|
|
}
|
|
});
|
|
const childNodeBindIP = config.childNodes.ip || config.bindip;
|
|
childNodeServer.listen(config.childNodes.port,childNodeBindIP,function(){
|
|
console.log(lang.Shinobi+' - CHILD NODE SERVER : ' + config.childNodes.port);
|
|
});
|
|
//send data to child node function
|
|
s.cx = function(data,connectionId){
|
|
childNodesConnectionIndex[connectionId].sendJson(data)
|
|
}
|
|
//child Node Websocket
|
|
childNodeWebsocket.on('connection', function (client, req) {
|
|
//functions for dispersing work to child servers;
|
|
const ipAddress = getIpAddress(req)
|
|
const connectionId = s.gid(10);
|
|
s.debugLog('Child Node Connection!',new Date(),ipAddress)
|
|
client.id = connectionId;
|
|
function onAuthenticate(d){
|
|
const data = JSON.parse(d);
|
|
const childNodeKeyAccepted = config.childNodes.key.indexOf(data.socketKey) > -1;
|
|
if(!client.shinobiChildAlreadyRegistered && data.f === 'init' && childNodeKeyAccepted){
|
|
initiateDataConnection(client,req,data,connectionId);
|
|
childNodesConnectionIndex[connectionId] = client;
|
|
client.removeListener('message',onAuthenticate)
|
|
client.on('message',(d) => {
|
|
const data = JSON.parse(d);
|
|
onWebSocketDataFromChildNode(client,data)
|
|
})
|
|
}else{
|
|
s.debugLog('Child Node Force Disconnected!',new Date(),ipAddress)
|
|
client.destroy()
|
|
}
|
|
}
|
|
client.on('message',onAuthenticate)
|
|
client.on('close',() => {
|
|
onDataConnectionDisconnect(client, req)
|
|
})
|
|
})
|
|
childNodeFileRelay.on('connection', function (client, req) {
|
|
function onAuthenticate(d){
|
|
const data = JSON.parse(d);
|
|
const childNodeKeyAccepted = config.childNodes.key.indexOf(data.socketKey) > -1;
|
|
if(!client.alreadyInitiated && data.fileType && childNodeKeyAccepted){
|
|
client.alreadyInitiated = true;
|
|
client.removeListener('message',onAuthenticate)
|
|
switch(data.fileType){
|
|
case'video':
|
|
initiateVideoWriteFromChildNode(client,data.options,data.connectionId)
|
|
break;
|
|
case'timelapseFrame':
|
|
initiateTimelapseFrameWriteFromChildNode(client,data.options,data.connectionId)
|
|
break;
|
|
}
|
|
}else{
|
|
client.destroy()
|
|
}
|
|
}
|
|
client.on('message',onAuthenticate)
|
|
})
|
|
}else
|
|
//setup Child for childNodes
|
|
if(
|
|
config.childNodes.enabled === true &&
|
|
config.childNodes.mode === 'child' &&
|
|
config.childNodes.host
|
|
){
|
|
const {
|
|
initiateConnectionToMasterNode,
|
|
onDisconnectFromMasterNode,
|
|
onDataFromMasterNode,
|
|
} = require('./childNode/childUtils.js')(s,config,lang,app,io)
|
|
s.connectedToMasterNode = false;
|
|
let childIO;
|
|
function createChildNodeConnection(){
|
|
childIO = createWebSocketClient('ws://'+config.childNodes.host + '/childNode',{
|
|
onMessage: onDataFromMasterNode
|
|
})
|
|
childIO.on('open', function(){
|
|
console.error(new Date(),'Child Nodes : Connected to Master Node! Authenticating...');
|
|
initiateConnectionToMasterNode()
|
|
})
|
|
childIO.on('close',function(){
|
|
onDisconnectFromMasterNode()
|
|
setTimeout(() => {
|
|
console.error(new Date(),'Child Nodes : Connection to Master Node Closed. Attempting Reconnect...');
|
|
createChildNodeConnection()
|
|
},3000)
|
|
})
|
|
childIO.on('error',function(err){
|
|
console.error(new Date(),'Child Nodes ERROR : ', err.message);
|
|
childIO.close()
|
|
})
|
|
}
|
|
createChildNodeConnection()
|
|
function sendDataToMasterNode(data){
|
|
childIO.send(JSON.stringify(data))
|
|
}
|
|
s.cx = sendDataToMasterNode;
|
|
// replace internal functions with bridges to master node
|
|
s.tx = function(x,y){
|
|
sendDataToMasterNode({f:'s.tx',data:x,to:y})
|
|
}
|
|
s.userLog = function(x,y){
|
|
sendDataToMasterNode({f:'s.userLog',mon:x,data:y})
|
|
}
|
|
s.queuedSqlCallbacks = {}
|
|
s.sqlQuery = function(query,values,onMoveOn){
|
|
var callbackId = s.gid()
|
|
if(!values){values=[]}
|
|
if(typeof values === 'function'){
|
|
var onMoveOn = values;
|
|
var values = [];
|
|
}
|
|
if(typeof onMoveOn === 'function')s.queuedSqlCallbacks[callbackId] = onMoveOn;
|
|
sendDataToMasterNode({f:'sql',query:query,values:values,callbackId:callbackId});
|
|
}
|
|
s.knexQuery = function(options,onMoveOn){
|
|
var callbackId = s.gid()
|
|
if(typeof onMoveOn === 'function')s.queuedSqlCallbacks[callbackId] = onMoveOn;
|
|
sendDataToMasterNode({f:'knex',options:options,callbackId:callbackId});
|
|
}
|
|
}
|
|
}
|