index.js 4.25 KiB
const PORT = 20000;
const MULTICAST_ADDR = "233.255.255.255";
const dgram = require("dgram");
const process = require("process");
var ip = require("ip");
const socket = dgram.createSocket({ type: "udp4", reuseAddr: true });
const CLI_HOST = "172.16.138.158";
const CLI_PORT = "5000";
socket.bind(PORT);
let connections = {};
const machineToIps = {
"0": "172.16.138.158",
"1": "172.22.156.15",
"2": "172.22.158.15",
"3": "172.22.154.16",
"4": "172.22.156.16",
"5": "172.22.158.16",
"6": "172.22.154.17",
"8": "172.22.158.17",
"9": "172.22.154.18",
"10": "172.22.156.18"
};
const IpsToMachine = {
"0.0.0.0": "0",
"172.16.138.158": "0",
"172.22.156.15": "1",
"172.22.158.15": "2",
"172.22.154.16": "3",
"172.22.156.16": "4",
"172.22.158.16": "5",
"172.22.154.17": "6",
"172.22.158.17": "8",
"172.22.154.18": "9",
"172.22.156.18": "10"
};
let machineNumber = IpsToMachine[ip.address()];;
socket.on("listening", function() {
socket.addMembership(MULTICAST_ADDR);
socket.setBroadcast(true);
setInterval(synAll, 1000);
const address = socket.address();
console.log(
`UDP socket listening on ${address.address}:${address.port} pid: ${
process.pid
} machine ${machineNumber}`
);
connections = {
"1": {
status: "alive",
timestamp: 0
}
};
});
function setConnections(machineIds) {
connections = {}
machineIds.forEach(element => {
connections[element.toString()] = {
status: "alive",
timestamp: 0
};
});
console.log("")
console.log("Machines | Status")
Object.keys(connections).map(connection => console.log(connection + " " + connections[connection].status))
console.log("")
}
function syn(machineNumberBeingChecked) {
const message = Buffer.from(`check ${machineToIps[machineNumber]}`);
socket.send(
message,
0,
message.length,
PORT,
machineToIps[machineNumberBeingChecked.toString()[0]],
function() {}
);
}
function ack(synIP, address) {
const message = Buffer.from(`ack ${machineNumber}`);
// console.log("ack " + machineNumber + " " + message.toString() )
socket.send(message, 0, message.length, PORT, address, function() {});
}
function synAll() {
Object.keys(connections).forEach(connection => {
// console.log(connection)
syn(connection)
})
}
function sendMessage() {
const message = JSON.stringify(connections);
socket.send(message, 0, message.length, CLI_PORT, CLI_HOST, function() {});
// console.log(connections)
}
function updateTimeStamp(ackMachineNumber) {
let ackMachineNumberWithTimestamp = Object.keys(connections).filter(m => m.toString()[0] === ackMachineNumber)
if ((ackMachineNumberWithTimestamp).length > 0) {
connections[ackMachineNumberWithTimestamp[0]].timestamp = Date.now()
}
}
function updateStatuses() {
Object.keys(connections).forEach(connection => {
if (Date.now() - connections[connection].timestamp >= 2000 && connections[connection].timestamp != 0) {
connections[connection].status = "dead"
const message = Buffer.from(`dead ${connection}`);
console.log(message.toString())
socket.send(
message,
0,
message.length,
PORT,
machineToIps["1"],
function() {}
);
delete connections[connection]
} else {
connections[connection].status = "alive"
}
})
}
socket.on("message", function(message, rinfo) {
const text = message.toString().split(" ");
if (text[0] === "initialize") {
setConnections(JSON.parse(text[1]))
}
if (text[0] === "list") {
sendMessage();
synAll(1)
console.log("")
console.log("Status")
Object.keys(connections).map(connection => console.log(connection + " " + connections[connection].status))
console.log("")
}
if (text[0] === "check") {
// console.log("GOT check")
ack(text[1], rinfo.address)
}
if (text[0] === "ack") {
updateTimeStamp(text[1])
updateStatuses()
}
if (text[0] === "leave") {
console.log(Object.keys(connections).filter(c => c.toString())
const deletedConnection = Object.keys(connections).filter(c => c.toString()[0] === text[1]);
console.log(text[1] + "left")
console.log(deletedConnection)
if (deletedConnection.length > 0) {
delete connections[deletedConnection[0]]
}
}
});