节点UDP数据包在递归函数中发送太多数据包

时间:2016-09-17 15:46:29

标签: javascript node.js recursion udp

我正在处理的代码有一个棘手的问题。基本上,此代码的目的是发送UDP广播,侦听响应(不是它刚刚发送的广播),并通过socket.io连接。递归用于确保数据包以1秒的间隔保持发送,直到给出响应。以下是代码的内容:

function requestBroadcast(message, broadcastPort) {
    var client = dgram.createSocket('udp4');
    client.bind(config.listenPort, function() {
        client.setBroadcast(true);
    })
    var receivedResponse = false;

    function checkResponse () {
        if (receivedResponse) {
            client.close();
            return;
        } else {
            console.error("!");
            client.send(message, 0, message.length, config.listenPort, config.broadcastAdd);
            client.on('message', function(msg, rinfo) {
                var msgObj = JSON.parse(msg);
                console.error(msgObj);
                if (!(msgObj.hasOwnProperty("KartNo"))) {
                    receivedResponse = true;
                    var socket = ioclient.connect("http://" + msgObj.address.toString() + ":" + msgObj.port.toString())
                }
            })
            setTimeout(checkResponse, 1000);
        }
    }
    checkResponse();
}

var msgObj = {KartNo: 38};
var msgObjStr = JSON.stringify(msgObj);
requestBroadcast(msgObjStr, 6000);

不幸的是,问题在于:递归函数的每次迭代,都会发送一个额外的数据包。例如,这是终端显示的内容。注意“!”在每次调用之后 - 递归函数仅在每次迭代时被调用一次,因此这不是问题。

!
{ KartNo: 38 }
!
{ KartNo: 38 }
{ KartNo: 38 }
!
{ KartNo: 38 }
{ KartNo: 38 }
{ KartNo: 38 }
!
{ KartNo: 38 }
{ KartNo: 38 }
{ KartNo: 38 }
{ KartNo: 38 }

我唯一的结论是,这必须与dgram模块本身有关,但我不能为我的生活弄清楚是什么。

这就是全部!任何帮助都将非常感激,并随时问我有关代码及其功能的任何问题。干杯!

1 个答案:

答案 0 :(得分:0)

问题在于,每次发送消息(message)时都要添加新的client.on('message', ...)事件侦听器。相反,只需在调用message后添加一个.bind()事件侦听器:

var client = dgram.createSocket('udp4');
client.bind(config.listenPort, function() {
    client.setBroadcast(true);
})
client.on('message', function(msg, rinfo) {
  var msgObj = JSON.parse(msg);
  console.error(msgObj);
  if (!(msgObj.hasOwnProperty("KartNo"))) {
    receivedResponse = true;
    var socket = ioclient.connect("http://" + msgObj.address.toString() + ":" + msgObj.port.toString())
  }
})
var receivedResponse = false;

function checkResponse () {
    if (receivedResponse) {
        client.close();
        return;
    } else {
        console.error("!");
        client.send(message, 0, message.length, config.listenPort, config.broadcastAdd);
        setTimeout(checkResponse, 1000);
    }
}