hjdhjd / homebridge-ratgdo

🚗 non-myQ Liftmaster, Chamberlain, and Ratgdo Plugin for Homebridge
Other
99 stars 2 forks source link

Backport http keep-alive configuration to enable EventSource reconnects #2

Closed egrim closed 6 months ago

egrim commented 6 months ago

Node.js v19 changed the default configuration of the built-in http agent used by EventSource to connect to Server Sent Events from ESPHome. Agents before this change did not use sockets with keep-alive enabled, preventing EventSource from detecting disruptions to the connection it uses to receive events.

Currently, the official homebridge docker container is based on Node.js v18, so this is likely to affect a large number of HBR users.

This change will detect if the node version is old enough not to have this behavior and configure the http (and https) modules to match behavior from more recent Node.js versions.

egrim commented 6 months ago

The following snippet demonstrates the issue:

const EventSource = require("eventsource");
const http = require("http");
const https = require("https");
const semver = require("semver");

const ratgdoIPAddress = <YOUR RATGDO IP ADDRESS>

let es = new EventSource(`http://${ratgdoIPAddress}/events`);

["message", "error", "open", "ping", "state", "log"].forEach((eventName) => {
    es.addEventListener(eventName, (eventData) => {
        console.log(`${eventName}:`, eventData);
    })
})

Substitute your ratgdo IP address and run it in both v18 and v19 of node. Restart or power-cycle your ratgdo, and the v18 will hang indefinitely, whereas the v19 instance will eventually reconnect and start receiving events again.

You can get even more status information by running with NODE_DEBUG configured to print http and net debug messages with:

NODE_DEBUG=http,net node <file-containing-script-above.js>
hjdhjd commented 6 months ago

Appreciate the PR and will incorporate a fix that addresses the underlying socket keepalive issue in the next release. It's worth noting (as I mentioned in another forum) this should fix the issue you identified, but not in the way you articulated:

That the defaults may have changed regarding HTTP keepalives in Node 19 doesn't directly impact homebridge-ratgdo or the underlying use of the EventSource API. When the underlying TCP socket disappears (e.g. a restart of the Ratgdo hardware), in containerized/virtualized environments, that connection loss may not be fully reported up the stack and the underlying HTTP connection never acknowledges it and reconnects.

The PR you submitted doesn't have anything (despite the identical naming) to do with HTTP keepalives directly. It has to do with the underlying socket/TCP keepalives, which is an altogether different thing. That's why it fixes the problem - it ensures that the TCP socket is kept alive and that the stack above it is informed, and it's not an HTTP keep alive. As mentioned, there will be a fix in the next release I'm curious to see you try out...hope this helps explain things.

Thanks again for the contribution!

github-actions[bot] commented 5 months ago

This issue is locked to prevent necroposting on closed issues. Please create a new issue for related discussion, if needed.