1

I'm trying to send a packet from my server to ping a client every few seconds in an infinite loop at all times.

This is the code I am running:

const dgram = require('dgram');
const message = Buffer.from('Some bytes');
const clientPing = dgram.createSocket('udp4');

const pinging = true;

function ping() {
  clientPing.send("Hi Uno", 8888, 'XXX.XX.XX.XXX', (err) => {
    clientPing.close();
  });
}

function sleep(time, callback) {
    var stop = new Date().getTime();
    while(new Date().getTime() < stop + time) {
        ;
    }
    callback();
}

function loop() {
  while(pinging == true) {
    sleep(3000, function() {
      ping();
      console.log('ping');
    });
  }
}

loop();

What's weird is that the console logs the string ping just fine at the given interval but the packet is never sent and never reaches my client. But when I run just ping(); outside of the loop the packet hits the client.

Udp isn't supposed to wait for a response after it sends the packet and doesn't wait for a response. What am I missing here?

3
  • 2
    You're blocking the event queue completely. Don't sleep synchronously. Commented Nov 22, 2018 at 2:47
  • I'm not sure what you mean. How would you loop this? I've tried it with setTimeout(() => { ping(); }, 3000); and the loop seems to run without waiting for the timeout to end. Commented Nov 22, 2018 at 2:50
  • node.js runs your Javascript single threaded. So, while you're in sleep() NOTHING else can get processed by your Javascript. Nothing. Thus, the value of pinging can never change unless it happens directly inside the while loop. No other events will ever get processed. This type of question has been covered multiple times here. Commented Nov 22, 2018 at 3:30

2 Answers 2

1

As @tkausl says, you're blocking the event loop. Don't use that sleep() function. Try something like this instead:

function loop() {
  if (!pinging) {
    return;
  }
  ping();
  console.log('ping');
  setTimeout(loop, 3000);
}

loop();
Sign up to request clarification or add additional context in comments.

1 Comment

I first had to comment out clientPing.close(); in order to get your code looping properly. Forgot to get rid of that from just the standalone file. Even after doing so though I was only seeing the console log the the ping but not see the packet reach my client. Though I think I found another method I answer below.
0

So I finally got it behave properly using this:

function loop() {

  setInterval(() => {
    clientPing.send("Hi Uno", 8888, 'XXX.XX.XX.XXX', (err) => {
    });
  }, 5000);

}

loop();

So now the Pi running this pings my arduino client successfully every 5s, the arduino then replies with temp and humidity data, the Pi server then catches it and pushes that to mongo.

2 Comments

There's no point in loop in this case. Just use setInterval directly.
I wanted to use it as an export from this module that my server file can import. So I did const loop = funtcion() { setInterval(() => {}, 3000); } in the end.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.