node-ethernet-ip icon indicating copy to clipboard operation
node-ethernet-ip copied to clipboard

Detect disconnection

Open pcnate opened this issue 5 years ago • 3 comments

Provide a disconnect event handler

Current Behavior

Disconnecting the PLC from the network does not get handled natively with the library. Attempting to read or write to it causes timeouts.

Expected Behavior

It would be nice to provide a disconnect callback to make it easier cleanup old connections and attempt to reconnect.

Possible Solution

    PLC.disconnect().then( () => {
      // do some connection cleanup, report offline, attempt reconnect etc
    });

Context

In order to detect whether the PLC is online, have to check for TIMEOUT errors thrown by _readTag, _writeTag, _readTagGroup, and _writeTagGroup but this requires actually reading or writing something. Some sort of defined watchdog type monitoring of the connecting would make code more concise and easier to understand.

pcnate avatar Sep 13 '18 13:09 pcnate

In the mean time, can I get some advice for how to clean up a stale connection due to the PLC going offline? I've tried to just reconnect, but it fails due to timeout.

kgustine avatar Feb 27 '20 03:02 kgustine

@pcnate What method did you end up going with as a work around?

cmseaton42 avatar Mar 02 '20 14:03 cmseaton42

I believe I solved a few problems related to this last week.

If your initial connection fails (or a reconnect attempt), you need to destory the socket via the native Socket destroy method. See the fix noted here https://github.com/cmseaton42/node-ethernet-ip/issues/65#issuecomment-574782328

If the connection has been established, but is then lost, you should call the Controller's destory method. Below is my actual code. I tested it with short resets of the EN2T ethernet card on the controller rack as well as long periods of being disconnected. This will reconnect when communication is reestablished. Note that this connect function is called after the controller object is created and I've subscribed to certain tags.

I have limited experience with sockets, so there may be hidden issues still. But this does recover from communication events and I believe addresses the TCP connection leak mentioned in the link above.

function connect() {
    PLC.connect(IP_ADDRESS, 0).then(() => {
        PLC.scan_rate = 1000;
        PLC.scan().catch(error => {
            PLC.destroy()
            setTimeout(connect, 5000)
        })
    }).catch(error => {
        net.Socket.prototype.destroy.call(PLC);
        setTimeout(connect, 5000)
    })
}

kgustine avatar Mar 02 '20 16:03 kgustine