jens-maus / node-unifi

NodeJS class for querying/controlling a UniFi-Controller (UDM-Pro, UDM-SE, UDM, UDR, UDW, CloudKey Gen1/Gen2) from Ubiquiti (www.ui.com)
MIT License
136 stars 49 forks source link

Websocket - Disconnect after every ~1 hour - need support #220

Open Scrounger opened 9 months ago

Scrounger commented 9 months ago

I am currently playing around with the websocket interface, with the long term goal of integrating this into the iobroker unifi adapter. I noticed that the websocket interface always stops working after about an hour, i have done serveral test. Unfortunately I do not get on now and need please support

Here you can find my test code: https://github.com/Scrounger/ioBroker.unifi/blob/1349aa3607ef147c66b2be3cc8acebfa9dfea6bb/main.js#L1423

And here are two logs of one run, all others show the same behaviour:

unifi-ws-log-1.log unifi-ws-log-2.log

Test setup: UDM Pro: v3.1.16 (Unifi OS) Network: 7.5.176

jens-maus commented 9 months ago

I am currently playing around with the websocket interface, with the long term goal of integrating this into the iobroker unifi adapter.

This is a very good idea and I personally also already thought about adapting iobroker.unifi to use websockets for status updates somehwere in the future, but I didn't find the time yet, actually. So please go ahead!

I noticed that the websocket interface always stops working after about an hour, i have done serveral test. Unfortunately I do not get on now and need please support

First of all, the websocket support in node-unifi is definitely not final and more or less in an early state. So there might be easily some shortcomings especially when used in such a complex environment/use case like iobroker.unifi. So there might be some issues with the ping/pong mechanism used to keepalive the websocket connect, but in the end we might need some smarter reconnection mechanism for long lived websocket connection, e.g. if network connectivity is not really stable (cf. https://stackoverflow.com/questions/50197453/how-long-can-a-websocket-connection-last).

Here you can find my test code: https://github.com/Scrounger/ioBroker.unifi/blob/1349aa3607ef147c66b2be3cc8acebfa9dfea6bb/main.js#L1423

Thx, to me this looks fine so far. However, before integrating this in iobroker.unifi I would propose to create a simple nodejs test example for establishing a long-lived websocket connection (e.g. which is based on the websocket example) and then see if the same issue appears there and then try to work out a solution in node-unifi for it.

Scrounger commented 9 months ago

I followed your suggestion and used a simple nodejs program to test. Unfortunately this shows exactly the same behavior, after about 1 hour the ws connection no longer works.

nodejs test code:

'use strict';

require('console-stamp')(console, 'yyyy-mm-dd HH:MM:ss.l');
const Unifi = require('node-unifi');
const unifi = new Unifi.Controller({
    host: '10.0.120.1',
    port: '',
    sslverify: false
});

(async () => {
    try {
        // LOGIN
        const loginData = await unifi.login('devBroker', 'yOVmU2M3MuEdy2jvJGW4');
        console.log('login: ' + loginData);

        // LISTEN for WebSocket events
        const listenData = await unifi.listen();
        console.log('listen: ' + listenData);

        // Listen for alert.client_connected
        unifi.on('alert.client_connected', function (data) {
            const ts = new Date(data[0].timestamp).toISOString();
            console.log(`${ts} - ${this.event}: ${data[0].parameters.CLIENT.id} (${data[0].parameters.CLIENT.name})`);
        });

        // Listen for alert.client_disconnected
        unifi.on('alert.client_disconnected', function (data) {
            const ts = new Date(data[0].timestamp).toISOString();
            console.log(`${ts} - ${this.event}: ${data[0].parameters.CLIENT.id} (${data[0].parameters.CLIENT.name})`);
        });

        // Listen for ctrl.* events
        unifi.on('ctrl.*', function () {
            console.log(`${this.event}`);
        });
    } catch (error) {
        console.log('ERROR: ' + error);
    }
})();

and the log: test.log

Maybe you can have a look at the implementation of the unifi-protect adapter. It also uses the websocket interface and can keep the connection permanently open. https://github.com/peterbaumert/ioBroker.unifi-protect/blob/master/protect_api/protect-api.js