Suggestion for BPUP: The timeout counter should be reset when each status message is sent. If that were the case, I could listen for with some pre-described timeout, say the suggested 60 seconds, and if the listen timesout, I could simply send the keep-alive and loop. If I get a status message back before the timeout, I could process the status message and loop, knowing that I still had (at least) the full 60 seconds before it would time out.
As it works now, I have to set my timeout to some sub-interval of the keep-alive time (say 20 seconds), and every time the listen comes back, whether with a status message or a timeout, I have to check the time of the last keep-alive message and calculate whether the keep-alive interval has expired, send the new keep-alive, store the time for the latest keep-alive, process any status message, all before I can loop back to the listen. Doable yes, but unnecessarily more complex than the simplicity of just letting the listen timeout be the timer for the need for a new keep-alive message.
Or you could sent the keep-alive totally independent of the receive cycle. Takes another thread for that, but easy enough in Python, which is what Iām using.
The transmission of a message from the Bond to the client doesnāt provide any information about the reachability of the client. This is why we donāt extend the timeout.
If we extended the timeout, and the Bond were sending one update message per minute (which will be the case if a fan is on Breeze mode), then client āconnectionsā would never timeout.
ātransmission of a message from the Bond to the client doesnāt provide any information about the reachability of the client.ā In the case of a direct socket connection, the send should fail if the socket was closed on the client side - I know this is the case in my integration if it is closed on the Bond side. In the event that the client stopped WITHOUT the socket closing AND the Bond is sending messages more frequently than once a minute for an extended period of time, then there would be the possibility that a number of messages could be sent that werenāt necessary. Would that be a huge resource loss? Regardless, I can deal with timeout (already have) - just trying to suggest ways to make the API simpler for IoT integrations.
I think youāre referring to the ICMP Destination Unreachable responses which some TCP/IP stacks return if you send an unsolicited UDP datagram, or send a datagram to a port where the corresponding socket has been closed.
We cannot rely on the ICMP errors here for several reasons, most significantly that if the host goes offline entirely, thereās nobody to send the ICMP error replies. Secondarily, a number of host stacks have stopped sending these error replies as a countermeasure against port scanners (though I could be wrong on that one). Lastly, this is just a SHOULD not a MUST in the specifications (RFC 1122 - Requirements for Internet Hosts - Communication Layers). So, we just rely on the UDP layer, ignoring the ICMP layer.
and I appreciate that. This kind of feedback is invaluable.
By the way, the timeout is 125 seconds, not 60. Itās designed so you just need to send one datagram each minute.
The client should continue to send the Keep-Alive datagram on the same socket every 60 seconds to keep the connection active. If no Keep-Alive datagram is received after 125 seconds, Bond will stop sending feedback to the client.
I just received your other reply (donāt know what happened to it in the display) and you make a good point: just send the keep-alive after every timeout OR status message is received. That would be very simple.
Actually, you canāt send it after every message received, because the ping itself causes a message. You would need to filter those out or you get a really bad loop. Donāt ask how I know.
For the Olibra folks lurking - you might notice a couple odd things in that code. First, Iām testing for a dict size of one to determine if the message was just the ping ack. It really would have been better if the message actually had a field that identified what kind of message it is.
Second, Iām adding an āidā field, because you didnāt include one that specifically identified which device this message pertains to. I had to pull it out of the topic field.