Как передать обновленную переменную вне события MQTT, чтобы использовать ее в качестве условия? (Hyperledger Fabri c & MQTT) - PullRequest
1 голос
/ 07 марта 2020

Во-первых, мы совсем новички в области Hyperledger Fabri c и MQTT. Мы создаем прототип с платформой Blockchain (Hyperledger Fabri c), написанной на nodeJS, и Raspberry Pi для передачи данных IoT (работа с mqtt). В нашем файле nodeJS мы создаем MQTT-клиент, который подписывается на topi c и получает в качестве сообщения объект JSON. Параметры этого объекта должны быть переданы в смарт-контракт (submitContract). Мы поняли, что шлюз для Hyperledger Fabri c отключается до того, как он запустит функции события MQTT (client.on), и поэтому мы подумали, что разрешаем шлюзу отключаться при условии представленного контракта (см. Код ниже). Для этого мы хотим получить переменную success из функции client.on("message"), чтобы мы могли использовать ее для оператора if в конце. Однако переменная успеха, похоже, не обновляется до success=true, просто используя return в client.on (), так что в конечном итоге программа никогда не завершается (иначе шлюз не отключается). Ниже вы видите части кода (соответствующие части). Кто-нибудь знает, как правильно передать обновленную переменную из функции события MQTT?

'use strict';

const { FileSystemWallet, Gateway } = require('fabric-network');
const mqtt = require("mqtt");

async function main() {
    try {
        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });

        // Get the network (channel) our contract is deployed to.
        const network = await gateway.getNetwork('mychannel');

        // Get the contract from the network.
        const contract = network.getContract('fabcar');

        //MQTT client connection & contract submission

        console.log("connecting to broker");
        const client = mqtt.connect("mqtt://192.168.43.217");
        var success = false;

        client.on("connect", () =>{
            console.log("Subscribing");
            client.subscribe("rfidData");
            console.log("Please hold your tag on the RFID reader. Wait...");
        });

        client.on("message", (topic, message) =>{
            var rfidPayload = JSON.parse(message.toString());
            var carKeyIn = rfidPayload.carKey;
            var renterIDIn = rfidPayload.renterID;
            var timestampIn = rfidPayload.timestamp;
            console.log(rfidPayload);

            contract.submitTransaction('openCar', carKeyIn, renterIDIn, timestampIn);
            success = true;
            console.log("Success? " + success);
            return success;
        });

        client.stream.on('error', (err) => {
            console.log('errorMessage', err);
            client.end()
        });       

        client.on("offline",() =>{
            console.log("offline");
        });

        client.on("reconnect", ()=>{
            console.log("reconnect");
        });

        // Disconnect from the gateway.
        if (success === true){
            client.end();
            gateway.disconnect();
        };

    } catch (error) {
        console.error(`Failed to submit transaction: ${error}`);
        process.exit(1);
    }
}

main();

1 Ответ

0 голосов
/ 07 марта 2020

Вам необходимо принять концепцию асинхронного выполнения и систем, управляемых событиями. Написанное вами приложение не выполняется в том порядке, в котором оно написано.

Обратный вызов on('message',....) будет выполнен только тогда, когда сообщение доставлено клиенту. Эта функция также не возвращает никаких значений (на самом деле она не вызывается никаким вашим кодом, она вызывается базовым клиентским кодом MQTT), поэтому она не будет «возвращать» значение success.

Если вы хотите, чтобы приложение отключилось после получения первого сообщения, проще всего переместить код, который отключает клиент MQTT и шлюз Fabri c, внутрь колбэка. например,

client.on("message", (topic, message) =>{
  var rfidPayload = JSON.parse(message.toString());
  var carKeyIn = rfidPayload.carKey;
  var renterIDIn = rfidPayload.renterID;
  var timestampIn = rfidPayload.timestamp;
  console.log(rfidPayload);

  contract.submitTransaction('openCar', carKeyIn, renterIDIn, timestampIn);

  gateway.disconnect();
  client.end();
});

РЕДАКТИРОВАТЬ: Глядя на do c, кажется, что submitTransaction() помечен как функция async, поэтому вы должны иметь возможность использовать await блокировать до завершения

  ...
  console.log(rfidPayload);

  await contract.submitTransaction('openCar', carKeyIn, renterIDIn, timestampIn);

  gateway.disconnect();
  client.end();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...