mirror of https://github.com/iotcat/wIoT
parent
afc71749ab
commit
593c1f0dbd
12 changed files with 1112 additions and 79 deletions
@ -0,0 +1,141 @@ |
||||
module.exports = (logger, node, ns) => { |
||||
|
||||
|
||||
const log = logger.getLogger('weblog'); |
||||
const express = require('express'); |
||||
const app = express() |
||||
const port = 3000; |
||||
|
||||
app.get('/', (req, res) => { |
||||
res.send('Hello World!') |
||||
}) |
||||
|
||||
app.listen(port, () => { |
||||
log.info('API web server begin at ', port); |
||||
}) |
||||
|
||||
function isJson(str) { |
||||
try { |
||||
if (typeof JSON.parse(str) == "object") { |
||||
return true; |
||||
} |
||||
} catch(e) { |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
app.get('/status', (req, res) => { |
||||
if(!req.query.hasOwnProperty('query')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
if(!isJson(req.query.query)){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
let query = JSON.parse(req.query.query); |
||||
|
||||
let resData = {}; |
||||
query.forEach(nid => { |
||||
if(node.hasOwnProperty(nid)){ |
||||
resData[nid] = {}; |
||||
resData[nid].status = node[nid].status; |
||||
resData[nid].funcID = node[nid].info.funcID; |
||||
resData[nid].port = node[nid].info.localport; |
||||
resData[nid].ip = node[nid].info.localip; |
||||
resData[nid].ns = node[nid].ns; |
||||
resData[nid].heap = node[nid].info.heap; |
||||
resData[nid].spiff = node[nid].info.spiff; |
||||
resData[nid].HeartbeatInterval = node[nid].info.HeartbeatInterval; |
||||
resData[nid].LastUpTime = node[nid].info.LastUpTime; |
||||
resData[nid].LastActiveTime = node[nid].info.LastActiveTime; |
||||
resData[nid].LastRefreshTime = node[nid].LastRefreshTime; |
||||
resData[nid].LastRestartTime = node[nid].LastRestartTime; |
||||
} |
||||
}); |
||||
|
||||
res.send(resData); |
||||
log.info('[status]', JSON.stringify(req.query.query)); |
||||
}) |
||||
|
||||
|
||||
|
||||
app.get('/setFunc', async (req, res) => { |
||||
if(!req.query.hasOwnProperty('nid') || !req.query.hasOwnProperty('funcID') || !req.query.hasOwnProperty('func')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
let nid = req.query.nid, |
||||
funcID = req.query.funcID, |
||||
func = new Buffer(req.query.func, 'base64').toString() |
||||
|
||||
if(!node.hasOwnProperty(nid)){ |
||||
res.status(404).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
if(!node[nid].status){ |
||||
res.status(503).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
let status = await node[nid].setFunc(funcID, func); |
||||
|
||||
|
||||
|
||||
res.send({status: status}); |
||||
log.info('[setFunc]', '<'+nid+'>', funcID, status); |
||||
}) |
||||
|
||||
|
||||
|
||||
app.get('/restart', async (req, res) => { |
||||
if(!req.query.hasOwnProperty('nid')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
let nid = req.query.nid; |
||||
|
||||
if(!node.hasOwnProperty(nid)){ |
||||
res.status(404).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
if(!node[nid].status){ |
||||
res.status(503).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
let status = await node[nid].restart(); |
||||
res.send({status: status}); |
||||
log.info('[restart]', '<'+nid+'>', status); |
||||
}) |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
app.get('/log', (req, res) => { |
||||
if(!req.query.hasOwnProperty('type') || !req.query.hasOwnProperty('start')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
res.send(); |
||||
log.info('[log]', req.query.type); |
||||
}) |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return null; |
||||
} |
@ -0,0 +1,29 @@ |
||||
module.exports = (node, nodetable) => { |
||||
|
||||
const LOG_PATH = __dirname + '/../data/log/'; |
||||
|
||||
|
||||
const log4js = require('log4js'); |
||||
|
||||
|
||||
log4js.configure({ |
||||
appenders: { |
||||
flow: {type: 'file', filename: LOG_PATH + 'flow.log'}, |
||||
access: {type: 'file', filename: LOG_PATH + 'access.log'}, |
||||
event: {type: 'file', filename: LOG_PATH + 'event.log'}, |
||||
nslog: {type: 'file', filename: LOG_PATH + 'ns.log'}, |
||||
weblog: {type: 'file', filename: LOG_PATH + 'web.log'}, |
||||
console: { type: 'console' } |
||||
}, |
||||
categories: { |
||||
flow: {appenders: ['flow'], level: 'info' }, |
||||
access: { appenders: ['access'], level: 'info' }, |
||||
event: {appenders: ['event', 'console'], level: 'info' }, |
||||
nslog: {appenders: ['nslog', 'console'], level: 'info' }, |
||||
weblog: {appenders: ['weblog', 'console'], level: 'info' }, |
||||
default: { appenders: ['console'], level: 'info' } |
||||
} |
||||
}); |
||||
|
||||
return log4js; |
||||
} |
@ -0,0 +1,280 @@ |
||||
module.exports = (logger, nodetable) => { |
||||
|
||||
|
||||
let nodes = {} |
||||
const CMD_DELAY = 200; |
||||
|
||||
let delay = (time_ms) => new Promise(resolve => { |
||||
setTimeout(()=>{ |
||||
resolve(); |
||||
}, time_ms); |
||||
}); |
||||
|
||||
|
||||
|
||||
const event = logger.getLogger('event'); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
nodetable.newNode((nid, info) => { |
||||
nodes[nid] = { |
||||
send: (name, body, isudp) => { |
||||
return nodetable.outgo(nid, { |
||||
to: nid, |
||||
from: "director", |
||||
name: name, |
||||
body: body |
||||
}, isudp); |
||||
}, |
||||
triggers: { |
||||
income: [ |
||||
function(name, body){ |
||||
if(name == '__getInfo'){ |
||||
nodes[nid].info.localport = body.port; |
||||
nodes[nid].info.localip = body.ip; |
||||
nodes[nid].info.funcID = body.funcID; |
||||
nodes[nid].info.HeartbeatInterval = body.HeartbeatInterval; |
||||
nodes[nid].ns = body.ns; |
||||
nodes[nid].LastRefreshTime = new Date().valueOf(); |
||||
} |
||||
}, |
||||
function(name, body){ |
||||
if(name == '__checkNS'){ |
||||
if(!nodes[nid].rns.hasOwnProperty(body.from) || nodes[nid].rns[body.from].ip != body.ip || nodes[nid].rns[body.from].port != body.port){ |
||||
nodes[nid].rns[body.from] = body; |
||||
nodes[nid].rns[body.from].updated = true; |
||||
} |
||||
nodes[nid].rns[body.from].LastCheckTime = new Date().valueOf(); |
||||
} |
||||
} |
||||
], |
||||
connect: [], |
||||
disconnect: [], |
||||
restart: [], |
||||
error: [] |
||||
}, |
||||
LastRefreshTime: 0, |
||||
LastRestartTime: 0, |
||||
ns: {}, |
||||
rns: {}, |
||||
on: (type, cb) => { |
||||
nodes[nid].triggers[type].push(cb); |
||||
}, |
||||
restart: () => new Promise((resolve) => { |
||||
let restartTime = new Date().valueOf(); |
||||
let counter = 100; |
||||
nodes[nid].send('__restart', ''); |
||||
let timer = () => { |
||||
setTimeout(()=>{ |
||||
if(nodes[nid].info.LastUpTime < restartTime){ |
||||
if(counter){ |
||||
if(nodes[nid].info.LastActiveTime > restartTime + 500){ |
||||
nodes[nid].send('__restart', ''); |
||||
restartTime = new Date().valueOf(); |
||||
counter = 100; |
||||
} |
||||
timer(); |
||||
counter --; |
||||
}else{ |
||||
resolve(false); |
||||
return; |
||||
} |
||||
}else{ |
||||
event.info('[CMD]', '<'+nid+'>', '__restart'); |
||||
resolve(true); |
||||
return; |
||||
} |
||||
}, 300); |
||||
}; |
||||
timer(); |
||||
}), |
||||
refresh: () => new Promise((resolve) => { |
||||
let startTime = new Date().valueOf(); |
||||
let counter = 100; |
||||
nodes[nid].send('__getInfo', ''); |
||||
let timer = () => { |
||||
setTimeout(async ()=>{ |
||||
if(nodes[nid].LastRefreshTime < startTime){ |
||||
if(counter){ |
||||
if(counter == 70 || counter == 40){ |
||||
nodes[nid].send('__getInfo', ''); |
||||
} |
||||
timer(); |
||||
counter--; |
||||
}else{ |
||||
resolve(false); |
||||
return; |
||||
} |
||||
}else{ |
||||
await delay(CMD_DELAY) |
||||
event.info('[CMD]', '<'+nid+'>', '__refresh'); |
||||
resolve(true); |
||||
return; |
||||
} |
||||
}, 300); |
||||
}; |
||||
timer(); |
||||
}), |
||||
setNS: (nsArr) => new Promise(async (resolve) => { |
||||
|
||||
|
||||
let checkLocalNS = () => Object.keys(nodes[nid].ns).every(id => { |
||||
if(nsArr.hasOwnProperty(id) && nodes[nid].ns[id].ip == nsArr[id].ip && nodes[nid].ns[id].port == nsArr[id].port){ |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
}) && Object.keys(nsArr).every(id => { |
||||
if(nodes[nid].ns.hasOwnProperty(id) && nodes[nid].ns[id].ip == nsArr[id].ip && nodes[nid].ns[id].port == nsArr[id].port){ |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
}); |
||||
|
||||
|
||||
|
||||
if(checkLocalNS()){ |
||||
resolve(true); |
||||
return; |
||||
} |
||||
|
||||
|
||||
let body = {}; |
||||
Object.keys(nsArr).forEach(id => { |
||||
body[id] = { |
||||
ip: nsArr[id].ip, |
||||
port: nsArr[id].port |
||||
} |
||||
}); |
||||
|
||||
|
||||
nodes[nid].send('__setNS', body); |
||||
|
||||
|
||||
await delay(CMD_DELAY); |
||||
|
||||
if(checkLocalNS()){ |
||||
event.info('[CMD]', '<'+nid+'>', '__setNS', JSON.stringify(Object.keys(body))); |
||||
resolve(true); |
||||
}else{ |
||||
resolve(false); |
||||
} |
||||
|
||||
}), |
||||
checkNS: (id, ip, port) => new Promise(async (resolve) => { |
||||
|
||||
nodes[nid].send('__checkNS', { |
||||
to: id, |
||||
from: nid, |
||||
ip: ip, |
||||
port: port |
||||
}, true); |
||||
|
||||
await delay(CMD_DELAY); |
||||
|
||||
nodes[nid].send('__checkNS', { |
||||
to: id, |
||||
from: nid, |
||||
ip: ip, |
||||
port: port |
||||
},true); |
||||
|
||||
await delay(CMD_DELAY); |
||||
|
||||
event.info('[CMD]', '<'+nid+'>', '__checkNS', id); |
||||
|
||||
}), |
||||
setFunc: (id, func) => new Promise(async resolve => { |
||||
let restartTime = new Date().valueOf(); |
||||
let counter = 100; |
||||
if(nodes[nid].info.funcID == id) { |
||||
resolve(true); |
||||
return;
|
||||
} |
||||
nodes[nid].send('__setFunc', { |
||||
func: { |
||||
id: id, |
||||
online: func |
||||
} |
||||
}); |
||||
let timer = () => { |
||||
setTimeout(()=>{ |
||||
if(nodes[nid].info.LastUpTime < restartTime || nodes[nid].info.funcID != id){ |
||||
if(counter){ |
||||
if(nodes[nid].info.LastActiveTime > restartTime + 500){ |
||||
nodes[nid].send('__setFunc', { |
||||
func: { |
||||
id: id, |
||||
online: func |
||||
} |
||||
}); |
||||
restartTime = new Date().valueOf(); |
||||
counter = 100; |
||||
} |
||||
timer(); |
||||
counter --; |
||||
}else{ |
||||
resolve(false); |
||||
return; |
||||
} |
||||
}else{ |
||||
event.info('[CMD]', '<'+nid+'>', '__setFunc', id, func); |
||||
resolve(true); |
||||
return; |
||||
} |
||||
}, 300); |
||||
}; |
||||
timer(); |
||||
}) |
||||
}; |
||||
nodes[nid].info = info; |
||||
}); |
||||
|
||||
|
||||
nodetable.connect((nid, info) => { |
||||
nodes[nid].status = true; |
||||
if(new Date().valueOf() < nodes[nid].info.LastUpTime + nodes[nid].info.HeartbeatInterval){ |
||||
nodes[nid].triggers.restart.forEach(cb => { |
||||
cb(); |
||||
}); |
||||
nodes[nid].LastRestartTime = new Date().valueOf(); |
||||
event.info('[RESTART]', '<'+nid+'>', '{'+info.funcID+'}'); |
||||
} |
||||
nodes[nid].triggers.connect.forEach(cb => { |
||||
cb(); |
||||
}); |
||||
event.info('[CONNECT]', '<'+nid+'>', '{'+info.funcID+'}'); |
||||
|
||||
}); |
||||
|
||||
|
||||
nodetable.disconnect((nid, info) => { |
||||
nodes[nid].status = false; |
||||
nodes[nid].triggers.disconnect.forEach(cb => { |
||||
cb(); |
||||
}); |
||||
event.info('[DISCONNECT]', '<'+nid+'>', '{'+info.funcID+'}'); |
||||
}); |
||||
|
||||
nodetable.income((nid, info, data) => { |
||||
nodes[nid].status = true; |
||||
nodes[nid].triggers.income.forEach(cb => { |
||||
cb(data.name, data.body); |
||||
}); |
||||
}); |
||||
|
||||
|
||||
nodetable.error((nid, info) => { |
||||
nodes[nid].triggers.error.forEach(cb => { |
||||
cb(info.error); |
||||
}); |
||||
event.error('[ERROR]', '<'+nid+'>', '{'+info.funcID+'}', info.error); |
||||
}); |
||||
|
||||
|
||||
return nodes; |
||||
} |
@ -0,0 +1,74 @@ |
||||
module.exports = (logger, node, nodetable) => { |
||||
|
||||
|
||||
const log = logger.getLogger('nslog'); |
||||
|
||||
|
||||
|
||||
const NS_DELAY = 2000; |
||||
|
||||
|
||||
let delay = (time_ms) => new Promise(resolve => { |
||||
setTimeout(()=>{ |
||||
resolve(); |
||||
}, time_ms); |
||||
}); |
||||
|
||||
|
||||
|
||||
let o = { |
||||
get: (nodeArr, refer) => new Promise(async resolve => { |
||||
let list = []; |
||||
nodeArr.forEach(nid => { |
||||
if(node.hasOwnProperty(nid)){ |
||||
list.push(nid); |
||||
} |
||||
}); |
||||
|
||||
let nsList = {}; |
||||
let beginTime = new Date().valueOf(); |
||||
list.forEach(nid1 => { |
||||
list.forEach(async nid2 => { |
||||
if(nid1 != nid2){ |
||||
log.info('[CHECK]', nid2, '-->', nid1); |
||||
await node[nid2].checkNS(nid1, refer && refer[nid2] && refer[nid2][nid1] && refer[nid2][nid1].ip || node[nid1].info.localip, refer && refer[nid2] && refer[nid2][nid1] && refer[nid2][nid1].port || node[nid1].info.localport) |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
await delay(NS_DELAY); |
||||
|
||||
list.forEach(nid => { |
||||
Object.keys(node[nid].rns).forEach(nid2 => { |
||||
let rns = node[nid].rns[nid2]; |
||||
if(rns.LastCheckTime > beginTime){ |
||||
log.info('[VERIFIED]', nid2, '-->', nid); |
||||
if(!nsList.hasOwnProperty(nid2)){ |
||||
nsList[nid2] = {}; |
||||
} |
||||
nsList[nid2][nid] = { |
||||
ip: rns.ip, |
||||
port: rns.port |
||||
} |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
|
||||
resolve(nsList); |
||||
|
||||
}), |
||||
set: (nsList) => new Promise(async resolve => { |
||||
let status = true; |
||||
Object.keys(nsList).forEach(async nidf => { |
||||
log.info('[SET]', nidf, '::', JSON.stringify(nsList[nidf])); |
||||
status = status && await node[nidf].setNS(nsList[nidf]); |
||||
}); |
||||
resolve(status); |
||||
}) |
||||
} |
||||
|
||||
|
||||
|
||||
return o; |
||||
} |
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue