Skip to content
Snippets Groups Projects
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]]
    }
  }

});