Skip to content
Snippets Groups Projects
  • Roman Azarenko's avatar
    21e0772c
    quickjs: remove console.log calls in async-mqtt.js · 21e0772c
    Roman Azarenko authored
    console.log outputs to stdout. This breaks CLI tools, which use stdout for outputting response JSON data.
    
    QuickJS doesn't support console.warn/console.error. Printing to stderr can be achieved with `std.err.puts()` or
    `std.err.printf()`.
    
    Alternatively, this kind of output should be put behind a verbose/debug flag.
    21e0772c
    History
    quickjs: remove console.log calls in async-mqtt.js
    Roman Azarenko authored
    console.log outputs to stdout. This breaks CLI tools, which use stdout for outputting response JSON data.
    
    QuickJS doesn't support console.warn/console.error. Printing to stderr can be achieved with `std.err.puts()` or
    `std.err.printf()`.
    
    Alternatively, this kind of output should be put behind a verbose/debug flag.
async-mqtt.js 2.31 KiB
import * as os from "os";
import * as std from "std";
import { WebSocket } from "/usr/lib/quickjs/websocket.js";

class AsyncClient {
  constructor() {
    globalThis.WebSocket = WebSocket;
    // paho-mqtt requires setTimeout and clearTimeout in global scope
    globalThis.setTimeout = os.setTimeout;
    globalThis.clearTimeout = function (timeout) {
      if (timeout) {
        os.clearTimeout(timeout);
      }
    };
    globalThis.global = globalThis;
    std.loadScript("/usr/lib/usp-js/lib/protobuf.min.js");
    std.loadScript("/usr/lib/usp-js/lib/paho-mqtt.min.js");
    protobuf.Root.prototype.fetch = function (filename, callback) {
      os.setTimeout(function () {
        const data = std.loadFile(filename);
        if (data === null)
          callback(new Error("failed to load file: " + filename));
        else
          callback(null, data);
      }, 0);
    };
  }

  async connectAsync(
    host = "localhost",
    port = 9001,
    user = "admin",
    password = "admin"
  ) {
    this.client = new Paho.Client(
      host,
      port,
      "/mqtt",
      "proto::interop-usp-controller"
    );
    const opts = {
      userName: user,
      password: password,
    };

    const client = this.client;
    const connectPromise = new Promise(function (resolve, reject) {
      opts.onFailure = function (err) {
        reject(new Error(err.errorMessage));
      };

      opts.onSuccess = function () {
        resolve(client);
      };
      client.connect(opts);
    });

    this.client = await connectPromise;
    // this.client.subscribe('/usp/controller/#')

    return this;
  }

  async subscribe(id) {
    this.client.subscribe(id);
  }

  async unsubscribe(id) {
    this.client.unsubscribe(id);
  }

  async on(msg, callback) {
    if (msg === "message") {
      this.client.onMessageArrived = function (msg) {
        callback(msg.payloadBytes);
      };
    } else if (msg === "error") {
      // there is no erro handling in paho mqtt
      this.client.onConnectionLost = function (responseObject) {
        callback(responseObject);
      };
    }
  }

  async publish(topic, msg) {
    this.client.send(topic, msg);
  }

  async end() {
    this.client.disconnect();
  }
}

async function main() {
  const client = new AsyncClient();
  await client.connect();
}

const mqttAsync = new AsyncClient();
export default mqttAsync;