arduino-libraries / WiFiNINA

139 stars 105 forks source link

Fastest way to check if host is up #73

Open ldiqual opened 5 years ago

ldiqual commented 5 years ago

I have a http server on my internal network. I need to detect whether the host is up in a quick manner so that I can send a wakeonlan packet if it isn't. So far the only ways I've found are:

  1. Ping the host, however it has a hardcoded 5s timeout
  2. Try to connect to the http server using WifiClient.connect, but this seems to have a hardcoded 10s timeout too.

I know for sure that this host will respond under 100ms. What would be the fastest way to either ping it, connect to it, or check that the relevant http port is open, with a cap at 100ms?

If this is not feasible as of now, how would you suggest me to implement it? A few suggestions: I could add an optional timeout param to the ping command, or a new command checkPortOpen(ip, port, timeout).

sandeepmistry commented 4 years ago

Hi @ldiqual,

We could consider having API's to override the default timeouts.

Would you like to submit a pull request with a proposal do so?

DesktopMan commented 4 years ago

A way of setting ping and connect timeouts would be very much appreciated. As it is now connect() triggers my watchdog if the server is down, which seems less than ideal.

hortynz commented 4 years ago

A way of setting ping and connect timeouts would be very much appreciated. As it is now connect() triggers my watchdog if the server is down, which seems less than ideal.

I have the same issue @DesktopMan. The longest watchdog I can set on the Uno Wifi rev.2 is ~2.2s. Even with host up, it's a 1.8s delay to get the client connection up. With site down it's a long delay - the 8s mentioned seems about right. Incidentally, I've found a lot of issues with a variety of comms related libraries in my search for a way to send logs and status information. It seems most don't think of reconnecting in the context of a short cycle responsive system.

I decided to avoid most comms libraries as a result and go as simple as possible - in my case WifiNina is needed and hence that and its client are the way forward.

I have experimented and found that the standard wifi connect routine in the library can be limited by setting the timeout, but eventually connects anyway. So I developed a 2 step system in my code, which initiates the request, then periodically checks for a connection (up to a longish timeout for retrying). The rest of the code just accepts that connections are transient.

That user set timeout doesn't currently exist for the client connection request. Initial experiments show that the connect routine can be split before it calls SpiDrv::waitForSlaveReady and return almost immediately. If I then call the followup functions after 2s the connection is made and all seems well.

My question is: if I use that split, and implement this into a separate function (I'd do SSL for host only) with a code example showing the technique, would that be something you want to adopt?

Update: I went ahead and coded it for my purpose. One issue is that returning control up to the user mid spi request means that I can't allow other related requests to process before that response is processed, even non client related ones (e.g. checking wifi status).

Alexander96f commented 3 years ago

Did anyone found a way to check if the Server is up without waiting more than 5 seconds if its not up?

hortynz commented 3 years ago

Yes, as I said, I changed the spidrv code, adding a 2 step system that is non blocking. It's tested for my purposes, but not widely, and I got no response to my early comment, so not sure how to get it into the shared code. Happy to share if you want it