LukasBombach / sblendid

A JavaScript Bluetooth Low Energy (BLE) Library
MIT License
61 stars 4 forks source link

Howto stop or kill connected process #7

Open dunda123 opened 4 years ago

dunda123 commented 4 years ago

Hi. It is possible to cancel the sblendid process? If I register an notify event:

characteristic.on("notify", (buff: Buffer) => {...}

it can currently only be terminated by process.exit(0). But this will end the main process of nodejs program.

Thanks.

marksyzm commented 4 years ago

Does characteristic.off() work?

dunda123 commented 4 years ago

I try this: peripheral.disconnect(); characteristic.off("notify", value => { console.log("Off Characteristic") }) The data stops reading, but the process remains unfinished if I close Electron application. I try a bluebird but also no result. It only works a hard spawn process. This is the same as noble. Thx.

marksyzm commented 4 years ago

You won’t be able to switch off the event with a new function like that. It has to be a reference to the same handler as that used with on.

dunda123 commented 4 years ago

Thx. But still same. I create now simple example:

import Sblendid from "@sblendid/sblendid";
import Service from "@sblendid/sblendid/dist/src/service";
import {BLEConst} from "../conf/BLEConst";
import Characteristic from "@sblendid/sblendid/dist/src/characteristic";

async function testSblendid(deviceMacAddress: string, serviceUuid: string): Promise<Characteristic> {
    const sbl = await Sblendid.powerOn();
    const peripheral = await Sblendid.connect(deviceMacAddress);
    const service: Service = await peripheral.getService(serviceUuid);

    const characteristics = await service.getCharacteristics();

    for (const characteristic of characteristics) {
        if (characteristic.uuid != BLEConst.WATCH_CHAR_HUMIDITY) {
            continue;
        }
        if (characteristic.properties.notify) {
            await characteristic.on("notify", notifyHandler);
            return characteristic;
        }
    }
}

const notifyHandler = (buff: Buffer) => {
    console.log("Read data->" + buff);
};

async function start() {
    let characteristic = await testSblendid(BLEConst.PERIPHAL_MAC_ADR, BLEConst.WATCH_SERVICE_UUID);

    setTimeout(() => {
        console.log("Characteristic Off");
        characteristic.off("notify", notifyHandler)
        //peripheral.disconnect();
    }, 10000);
}

start();

My stupid question is: How to exit a program without calling process.exit(0).

It will help me a lot. I have a bad day :)

LukasBombach commented 4 years ago

@dunda123 this is probably my bad. I have seen issues that the process does not exit once you add an event listener. The background (probably) is that I mismanage event listeners in the library. I have seen this behavior before in my tests, but I wasn't sure this was a mistake or a problem. Basically I (probably) don't unregister some some internal event listeners that get triggered by your event listener. The good news is, I can fix this. The bad news is, you'll have to wait for v1.0.0. It would be to complicated at this stage of the project to only fix this in an isolated manner. I'd say give it maybe 3 weeks, I hope I can release v1.0.0 by then. Until then it's process.exit(). Sorry.

LukasBombach commented 4 years ago

Ok, I think I found the root of this. I want to finish Linux support first (https://github.com/LukasBombach/sblendid/issues/4) because then the library is feature-complete.

This is just a note for myself, it does not have to make sense for you, but I need to put it somewhere and I think this is the right place:

Characteristics only subscribe once. Even when multiple listeners have been added, the subscripion ist only create once and all listeners are just attached to an event listener. However, the characteristic object itself might be created multiple times, so that there are dead and lost characteristic instances with event listeners attached to them.

LukasBombach commented 4 years ago

@dunda123 which OS do you use? macOS oder Windows?

dunda123 commented 4 years ago

@dunda123 which OS do you use? macOS oder Windows?

Windows 10. Thx.

LukasBombach commented 4 years ago

Ok, @geovie helped me track down the bug at https://github.com/Timeular/noble-mac/issues/41 , fix will come soon

LukasBombach commented 4 years ago

Hey @dunda123 so what was happening here was that by using Sblendid you were powering on the Bluetooth adapter of your computer and the Node process would keep running until that adapter is powered off again.

I have added a powerOff() method to Sblendid, as an instance and a class method.

import Sblendid from "@sblendid/sblendid";

const instance = await Sblendid.powerOn();
await instance.powerOff();

// or

Sblendid.powerOff();

In your example, if you update sblendid and the adapter

npm i @sblendid/sblendid
npm i @sblendid/adapter-node

you can now do

await sbl.powerOff();
dunda123 commented 4 years ago

Hi. Sorry for the late reply. I try powerOff() on Windows 10:

import Sblendid from "@sblendid/Sblendid";

let sblend: Sblendid;

const testOnOff = async () => {
    Sblendid.powerOn().then((value) => {
        console.log("PowerOn OK:", value);
        sblend = value;
        sblend.powerOff().then((value) => {
            console.log("powerOff() ok:", value);
        }).catch((err) => {
            console.log("powerOff() error:", err);                
        })
    }).catch((err) => {
        console.log("powerOn() error:", err);
    });
};

testOnOff().then((value) => {
    console.log("Def OK:", value);

}).catch((err) => {
    console.log("!!Def Err:", err);
});

but this code throw next Exception:

powerOff() error: TypeError: this.bindings.stop is not a function
    at n.stop (f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:3799)
    at Function.<anonymous> (f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:6880)
    at f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:1566
    at Object.next (f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:1671)
    at f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:598
    at new Promise (<anonymous>)
    at __awaiter (f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:372)
    at Function.n.powerOff (f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:6758)
    at Function.powerOff (f:\projects\nodejs\testBlending\node_modules\@sblendid\adapter-node\dist\index.cjs.js:16:11614)
    at t.<anonymous> (f:\projects\nodejs\testBlending\node_modules\@sblendid\Sblendid\src\sblendid.ts:38:19)

After the error is displayed, the program is still running.

Thx.

LukasBombach commented 4 years ago

Ah dammit, ok I need to reopen this