|
|
MQTTÐÒéʾÀýAIWROK°æ
- /**
- * MQTT ÐÒéʾÀý - AIWROK °æ
- *
- * ʹÓà Eclipse Paho Java ¿Í»§¶ËʵÏÖ MQTT v3.1.1 Á¬½Ó
- *
- * v5 ˵Ã÷£ºdex Ϊ¹Ù·½ Paho 1.2.5 Ô´ÂëÐÞ²¹°æ£¨2026-08-29 ÖØ½¨£©£º
- * 1. LoggerFactory ×ÊÔ´°ü²éÕÒ¼Ó±£»¤£¬Ä¬ÈÏʹÓà MockLogger£¨ÎÞ²Ù×÷ÈÕÖ¾£©
- * ¡ú ÐÞ¸´ dex »·¾³Ï ResourceBundle.getBundle ±ØÅ× MissingResourceException
- * 2. NetworkModuleService ¼ÓÄÚÖÃÐÒ鹤³§¶µµ×£¨tcp/ssl/ws/wss£©
- * ¡ú ÐÞ¸´ dex ÎÞ META-INF/services µ¼ÖÂ "no NetworkModule installed for scheme tcp"
- * 3. ½Å±¾²»ÔÙÐèÒªÈκÎÔËÐÐʱ·´Éä²¹¶¡
- * Ö§³Ö£º·¢²¼/¶©ÔÄģʽ¡¢QoS 0/1/2¡¢×Ô¶¯ÖØÁ¬¡¢ÒÅÖöÏûÏ¢¡¢ÐÄÌø±£»î
- *
- * MQTT vs WebSocket Çø±ð£º
- * MQTT ÊÇÇáÁ¿¼¶·¢²¼/¶©ÔÄÏûÏ¢ÐÒ飬ÊÊºÏ IoT/ÒÆ¶¯¶Ë
- * ±È WebSocket ¸üÊ¡µç¡¢¸üÊ¡Á÷Á¿£¬Ö§³Ö QoS ÏûÏ¢ÖÊÁ¿±£Ö¤
- * Ö§³ÖÖ÷Ìâ(Topic)¶©ÔÄ£¬ÏûϢ·ÓɸüÁé»î
- *
- * ÒÀÀµ¼ÓÔØ£¨×Ô¶¯£¬ÎÞÐèÊÖ¶¯²Ù×÷£©£º
- * dex Îļþ·ÅÔÚ H5HTML/²å¼þ/ Ŀ¼£¬AIWROK µÄ loadDex ×Ô¶¯¼ÓÔØ
- * loadDex Ö»´Ó"²å¼þ"Ŀ¼¼ÓÔØ£¬ÇÒÐèÒª .dex ¸ñʽ£¨²»ÊÇ .jar£©
- *
- * dex ÎļþÒÑËæ¹¤³Ì´ò°üÔÚ£ºH5HTML/²å¼þ/paho-mqtt.dex
- * Èç¹û²å¼þĿ¼ûÓÐ dex£¬×Ô¶¯´Ó´úÂëĿ¼µÄ paho-mqtt-dex-b64.js »¹Ô
- *
- * ʹÓ÷½·¨£º
- * 1. ÐÞ¸Ä CFG ÖÐµÄ broker µØÖ·¡¢¶Ë¿Ú¡¢Óû§ÃûÃÜÂë
- * 2. AIWROK ÖÐÖ±½ÓÔËÐб¾½Å±¾
- * 3. ÈÕÖ¾´°¿Ú²é¿´Á¬½Ó״̬ºÍÊÕ·¢ÏûÏ¢
- */
- // ========== ¼ÓÔØ Paho MQTT Java ¿â ==========
- // AIWROK loadDex Ö»´Ó H5HTML/²å¼þ/ Ŀ¼¼ÓÔØ .dex Îļþ
- // AIWROK IDE ²»»áͬ²½²å¼þĿ¼µÄ¶þ½øÖÆÎļþµ½ÊÖ»ú£¬
- // ½Å±¾ÔËÐÐʱ´ÓÄÚǶµÄ base64 Êý¾Ý×Ô¶¯»¹Ô dex Îļþµ½²å¼þĿ¼
- var loaded = false;
- // ÊÖ»ú¶Ë·¾¶
- var sdcardPath = "/sdcard";
- var projectRoot = sdcardPath + "/auto/H5HTML";
- var pluginDir = projectRoot + "/²å¼þ";
- var codeDir = projectRoot + "/´úÂë";
- var dexFileName = "paho-mqtt.dex";
- var dexTargetPath = pluginDir + "/" + dexFileName;
- // dex °æ±¾Åж¨£ºÒÔÄÚǶ base64 ½âÂëºóµÄ³¤¶ÈΪΨһ»ù×¼
- // £¨ÕâÑùÒÔºóÖØÐ´ò°ü dex ²»±Ø¸ÄÈκγ£Á¿£¬½Å±¾×Ô¼º»á±È¶Ô²¢¸²¸Ç¾É°æ£©
- function fileSize(path) {
- try {
- var f = new java.io.File(path);
- return f.exists() ? Number(f.length()) : -1;
- } catch (e) { return -1; }
- }
- // ÏÈÈ¡ÄÚǶÊý¾Ý£ºrequire ʧ°ÜÖ»¼ÇÈÕÖ¾£¬²»Èýű¾±À
- var dexBytes = null;
- try {
- try { require("paho-mqtt-dex-b64.js"); } catch (reqErr) {
- printl("[WARN] require paho-mqtt-dex-b64.js ʧ°Ü: " + reqErr.message);
- }
- if (typeof PAHO_MQTT_DEX_B64 !== "undefined" && PAHO_MQTT_DEX_B64) {
- dexBytes = java.util.Base64.getDecoder().decode(PAHO_MQTT_DEX_B64);
- printl("[INFO] ÄÚǶ dex Êý¾Ý: " + dexBytes.length + " bytes");
- } else {
- printl("[WARN] δȡµ½ÄÚǶ base64 Êý¾Ý£¨PAHO_MQTT_DEX_B64 Ϊ¿Õ£©");
- }
- } catch (e) {
- printl("[WARN] ÄÚǶ dex ½âÂëʧ°Ü: " + e.message);
- dexBytes = null;
- }
- var expectedSize = dexBytes ? Number(dexBytes.length) : -1;
- var curSize = fileSize(dexTargetPath);
- var dexWasThere = curSize > 0;
- // ÓÐÄÚǶÊý¾Ý¾Í°´×Ö½ÚÊýÅа汾£»Ã»ÓоÍ"ÓÐ dex ÏÈÓÃ×Å"
- var verOk = (expectedSize > 0) ? (curSize === expectedSize) : dexWasThere;
- printl("[INFO] ²å¼þĿ¼ dex: " + (dexWasThere ? ("ÒÑ´æÔÚ " + curSize + " bytes") : "²»´æÔÚ") +
- "£¬" + (verOk ? "°æ±¾Ð£Ñéͨ¹ý" : ("Ðè֨װ£¨ÆÚÍû " + (expectedSize > 0 ? expectedSize : "δ֪") + " bytes£©")));
- // µÚÒ»²½£ºÈ·±£²å¼þĿ¼´æÔÚ
- try { file.mkdir(pluginDir); } catch (e) {}
- // µÚ¶þ²½£º°æ±¾²»¶Ô¾ÍÓÃÄÚǶÊý¾Ý¸²¸Ç»¹Ô
- var installed = false;
- if (!verOk && dexBytes) {
- try {
- var fos = new java.io.FileOutputStream(dexTargetPath);
- fos.write(dexBytes);
- fos.close();
- printl("[INFO] ÒÑ»¹Ô " + dexFileName + " µ½²å¼þĿ¼");
- installed = true;
- } catch (e) {
- printl("[WARN] дÈë dex ʧ°Ü: " + e.message);
- }
- }
- // ×îÖÕÅж¨ÄÜ·ñ¼ÓÔØ£º»¹Ô³É¹¦£¬»òÊÖ»úÉϱ¾À´¾ÍÓÐ dex£¨ÍË»ØÊ¹ÓÃÏÖÓÐÎļþ£©
- var dexExists = installed || dexWasThere;
- if (!installed && !verOk && dexWasThere) {
- printl("[WARN] ÄÚǶ»¹ÔδÍê³É£¬¸ÄÓÃÊÖ»úÉÏÏÖÓÐµÄ dex ¼ÌÐø¼ÓÔØ");
- }
- // µÚÈý²½£ºÓà loadDex ¼ÓÔØ
- if (dexExists) {
- try {
- rhino.loadDex(dexFileName);
- printl("[INFO] Paho MQTT ¼ÓÔØ³É¹¦ (loadDex: " + dexFileName + ")");
- loaded = true;
- } catch (e) {
- printl("[WARN] loadDex ʧ°Ü: " + e.message + "£¬³¢ÊÔÍêÕû·¾¶...");
- try {
- rhino.loadDex(dexTargetPath);
- printl("[INFO] Paho MQTT ¼ÓÔØ³É¹¦ (loadDex ÍêÕû·¾¶)");
- loaded = true;
- } catch (e2) {
- printl("[WARN] loadDex ÍêÕû·¾¶Ò²Ê§°Ü: " + e2.message);
- }
- }
- } else {
- try {
- rhino.loadDex(codeDir + "/paho-mqtt.dex");
- printl("[INFO] Paho MQTT ¼ÓÔØ³É¹¦ (loadDex: ´úÂëĿ¼)");
- loaded = true;
- } catch (e) {
- printl("[WARN] loadDex(´úÂëĿ¼) ʧ°Ü: " + e.message);
- }
- }
- if (!loaded) {
- printl("[WARN] ×Ô¶¯¼ÓÔØÊ§°Ü£¬³¢ÊÔÖ±½Ó importClass...");
- }
- // ========== µ¼Èë Paho MQTT Java Àà ==========
- // ÉèÖÃÓ¢ÎÄ locale£¬±ÜÃâ Paho ²éÕÒÖÐÎÄ×ÊÔ´°üʧ°Ü
- try {
- java.util.Locale.setDefault(java.util.Locale.ENGLISH);
- } catch (e) {}
- try {
- importClass(Packages.org.eclipse.paho.client.mqttv3.MqttClient);
- importClass(Packages.org.eclipse.paho.client.mqttv3.MqttConnectOptions);
- importClass(Packages.org.eclipse.paho.client.mqttv3.MqttCallback);
- importClass(Packages.org.eclipse.paho.client.mqttv3.MqttMessage);
- importClass(Packages.org.eclipse.paho.client.mqttv3.MqttException);
- importClass(Packages.org.eclipse.paho.client.mqttv3.persist.MemoryPersistence);
- importClass(Packages.org.eclipse.paho.client.mqttv3.IMqttDeliveryToken);
- importClass(Packages.org.eclipse.paho.client.mqttv3.MqttTopic);
- printl("[INFO] Paho MQTT ÀർÈë³É¹¦");
- } catch (e) {
- printl("[FATAL] Paho MQTT ÀർÈëʧ°Ü: " + e.message);
- printl("[FATAL] ÇëÈ·±£ paho-mqtt.dex ÔÚ H5HTML/²å¼þ/ Ŀ¼");
- printl("[FATAL] dex ÎļþÒÑËæ¹¤³Ì´ò°üÔÚ: H5HTML/²å¼þ/paho-mqtt.dex");
- printl("[FATAL] ÈçÐèÊÖ¶¯ÏÂÔØ jar ²¢×ª»»: https://repo1.maven.org/maven2/org/eclipse/paho/org.eclipse.paho.client.mqttv3/1.2.5/org.eclipse.paho.client.mqttv3-1.2.5.jar");
- printl("[FATAL] ת»»ÃüÁî: java -cp dx.jar com.android.dx.command.Main --dex --output=paho-mqtt.dex paho-mqtt.jar");
- exit();
- }
- // ========== ÅäÖÃ ==========
- var CFG = {
- // MQTT Broker µØÖ·£¨TCP ·½Ê½£©
- brokerUrl: "tcp://broker.emqx.io:1883",
- // ¿Í»§¶Ë ID£¨Áô¿Õ×Ô¶¯Éú³É£©
- clientId: "",
- // Óû§ÃûÃÜÂë
- username: "",
- password: "",
- // ÐÄÌø¼ä¸ô£¨Ã룩
- keepAliveSec: 30,
- // Á¬½Ó³¬Ê±£¨Ã룩
- connectTimeoutSec: 15,
- // »á»°Çå³ý±êÖ¾
- cleanSession: true,
- // ÒÅÖöÏûÏ¢£¨LWT£©
- willTopic: "",
- willMessage: "",
- willQos: 0,
- willRetained: false,
- // ×Ô¶¯ÖØÁ¬
- autoReconnect: true,
- reconnectDelayMs: 3000,
- maxReconnectDelayMs: 30000,
- // ĬÈÏ QoS
- defaultQos: 1,
- // ¶©ÔÄÖ÷ÌâÁбí
- subscribeTopics: [
- { topic: "aiwrok/cmd/+", qos: 1 },
- { topic: "aiwrok/broadcast", qos: 0 },
- { topic: "aiwrok/status/request", qos: 1 }
- ],
- // ·¢²¼Ö÷Ìâǰ׺
- pubTopicPrefix: "aiwrok",
- // µ÷ÊÔÈÕÖ¾
- debug: true,
- // ½Å±¾ÔËÐÐʱ³¤£¨ºÁÃ룩£¬0=ÎÞÏÞ
- runDuration: 0
- };
- // ========== È«¾Ö״̬ ==========
- var G = {
- mqttClient: null,
- connected: false,
- running: true,
- startTime: 0,
- msgSentCount: 0,
- msgRecvCount: 0,
- reconnectCount: 0
- };
- // ========== ʱ¼ä¹¤¾ß ==========
- function nowMs() {
- return (new Date()).getTime();
- }
- function nowSec() {
- return Math.floor(nowMs() / 1000);
- }
- // ========== É豸ÐÅÏ¢ ==========
- function getDeviceInfo() {
- var info = {
- imei: "",
- brand: "",
- model: "",
- android: "",
- screen: ""
- };
- try { info.imei = device.getIMEI() || ""; } catch (e) {}
- try { info.brand = device.getBrand() || ""; } catch (e) {}
- try { info.model = device.getModel() || ""; } catch (e) {}
- try { info.android = java.lang.System.getProperty("os.version") + ""; } catch (e) {}
- try { info.screen = screen.getScreenWidth() + "x" + screen.getScreenHeight(); } catch (e) {}
- return info;
- }
- // ========== Éú³É¿Í»§¶Ë ID ==========
- function generateClientId() {
- var info = getDeviceInfo();
- var ts = nowMs();
- var rand = Math.floor(Math.random() * 10000);
- return "aiwrok_" + (info.imei || info.model || "dev") + "_" + ts + "_" + rand;
- }
- // ========== »ñÈ¡·¢²¼Ö÷Ìâ ==========
- function getPubTopic(suffix) {
- return CFG.pubTopicPrefix + "/" + suffix;
- }
- // ========== ·¢²¼ÏûÏ¢ ==========
- function publish(topic, payload, qos) {
- if (!G.connected || !G.mqttClient) {
- printl("[WARN] δÁ¬½Ó£¬ÎÞ·¨·¢²¼: " + topic);
- return false;
- }
- if (qos == null) qos = CFG.defaultQos;
- try {
- var content;
- if (typeof payload === "string") {
- content = payload;
- } else {
- content = JSON.stringify(payload);
- }
- var msg = new MqttMessage();
- msg.setPayload(new java.lang.String(content).getBytes("UTF-8"));
- msg.setQos(qos);
- G.mqttClient.publish(topic, msg);
- G.msgSentCount++;
- printl("[PUB] " + topic + " qos=" + qos + " len=" + content.length);
- return true;
- } catch (e) {
- printl("[ERROR] ·¢²¼Òì³£: " + e.message);
- return false;
- }
- }
- // ========== ´¦ÀíÊÕµ½µÄÏûÏ¢ ==========
- function handleMessage(topic, message) {
- G.msgRecvCount++;
- var payload = "";
- try {
- payload = "" + new java.lang.String(message.getPayload(), "UTF-8");
- } catch (e) {
- try { payload = String(message); } catch (e2) { payload = "" + message; }
- }
- printl("[SUB] " + topic + " len=" + payload.length + " | " + payload.slice(0, 200));
- var obj = null;
- try {
- obj = JSON.parse(payload);
- } catch (e) {
- printl("[DEBUG] ·Ç JSON ÏûÏ¢: " + payload.slice(0, 100));
- return;
- }
- if (topic.indexOf("cmd/") >= 0) {
- handleCmdMessage(topic, obj);
- } else if (topic.indexOf("broadcast") >= 0) {
- printl("[INFO] ¹ã²¥ÏûÏ¢: " + (obj.msg || payload.slice(0, 100)));
- } else if (topic.indexOf("status/request") >= 0) {
- handleStatusRequest(topic, obj);
- } else {
- printl("[DEBUG] δ´¦ÀíµÄÖ÷Ìâ: " + topic);
- }
- }
- // ========== ´¦ÀíÃüÁîÏûÏ¢ ==========
- function handleCmdMessage(topic, obj) {
- var cmd = obj.cmd || obj.type || "";
- printl("[INFO] ÊÕµ½ÃüÁî: " + cmd);
- if (cmd === "SCREENSHOT") {
- try {
- var bitmap = screen.screenShotFull();
- if (!bitmap) {
- publish(getPubTopic("resp/screenshot"), { ok: false, msg: "½ØÍ¼·µ»Ø¿Õ" });
- return;
- }
- var base64 = "" + bitmap.toBase64();
- try { bitmap.recycle(); } catch (e) {}
- publish(getPubTopic("resp/screenshot"), {
- ok: true,
- cmdId: obj.cmdId,
- base64: base64,
- length: base64.length
- });
- } catch (e) {
- publish(getPubTopic("resp/screenshot"), { ok: false, msg: e.message });
- }
- } else if (cmd === "CLICK") {
- try {
- var x = parseInt(obj.data.x, 10);
- var y = parseInt(obj.data.y, 10);
- if (isNaN(x) || isNaN(y)) {
- publish(getPubTopic("resp/click"), { ok: false, msg: "×ø±êÎÞЧ" });
- return;
- }
- if (typeof action !== "undefined") {
- action.click(x, y);
- } else if (typeof hid !== "undefined") {
- hid.click(x, y);
- }
- publish(getPubTopic("resp/click"), { ok: true, cmdId: obj.cmdId, x: x, y: y });
- } catch (e) {
- publish(getPubTopic("resp/click"), { ok: false, msg: e.message });
- }
- } else if (cmd === "STATUS") {
- handleStatusRequest(topic, obj);
- } else if (cmd === "HOME") {
- try { if (typeof hid !== "undefined") hid.home(); } catch (e) {}
- } else if (cmd === "BACK") {
- try { if (typeof hid !== "undefined") hid.back(); } catch (e) {}
- } else {
- printl("[DEBUG] δ֪ÃüÁî: " + cmd);
- }
- }
- // ========== ´¦Àí״̬²éѯ ==========
- function handleStatusRequest(topic, obj) {
- var info = getDeviceInfo();
- info.ok = true;
- info.cmdId = obj.cmdId;
- info.runtimeSec = nowSec() - G.startTime;
- info.msgSentCount = G.msgSentCount;
- info.msgRecvCount = G.msgRecvCount;
- info.reconnectCount = G.reconnectCount;
- publish(getPubTopic("resp/status"), info);
- }
- // ========== ¶©ÔÄÖ÷Ìâ ==========
- function subscribeTopics() {
- if (!G.connected || !G.mqttClient) return;
- for (var i = 0; i < CFG.subscribeTopics.length; i++) {
- var item = CFG.subscribeTopics[i];
- try {
- G.mqttClient.subscribe(item.topic, item.qos);
- printl("[INFO] ÒѶ©ÔÄ: " + item.topic + " qos=" + item.qos);
- } catch (e) {
- printl("[ERROR] ¶©ÔÄʧ°Ü " + item.topic + ": " + e.message);
- }
- }
- }
- // ========== MQTT »Øµ÷ʵÏÖ ==========
- function createMqttCallback() {
- return new MqttCallback({
- connectionLost: function (cause) {
- G.connected = false;
- var msg = "unknown";
- try { msg = String(cause.getMessage()); } catch (e) {}
- printl("[WARN] Á¬½Ó¶Ï¿ª: " + msg);
- },
- messageArrived: function (topic, message) {
- try {
- handleMessage("" + topic, message);
- } catch (e) {
- printl("[ERROR] ÏûÏ¢´¦ÀíÒì³£: " + e.message);
- }
- },
- deliveryComplete: function (token) {
- printl("[DEBUG] ÏûϢͶµÝÍê³É");
- }
- });
- }
- // ========== Á¬½Óʧ°ÜͳһÕï¶Ï´òÓ¡£¨·Ö½×¶Î¶¨Î» + JS/Java Ë«¶ÑÕ»£© ==========
- function logConnErr(stage, e) {
- var errMsg = "" + e;
- try {
- if (e instanceof MqttException) {
- errMsg = "MQTT Error " + e.getReasonCode() + ": " + e.getMessage();
- }
- } catch (e2) {}
- printl("[ERROR] " + stage + " ʧ°Ü: " + errMsg);
- // Rhino µÄ e.stack Ö¸Ïò½Å±¾ÐкÅ
- try { printl("[ERROR] " + stage + " JS¶ÑÕ»: " + (e.stack || "(ÎÞ)")); } catch (e3) {}
- // e.javaException Êǵײã Java Throwable£¨Rhino °ü×°¶ÔÏó±¾Éí²»ÄÜÖ±½Ó printStackTrace£©
- try {
- var je = e.javaException;
- if (je) {
- var sw = new java.io.StringWriter();
- var pw = new java.io.PrintWriter(sw);
- je.printStackTrace(pw);
- pw.flush();
- printl("[ERROR] " + stage + " Java¶ÑÕ»: " + sw.toString());
- }
- } catch (e4) {}
- }
- // ========== ½¨Á¢Á¬½Ó ==========
- // ²ð³É 3 ¸ö½×¶Î·Ö±ð try/catch£ºÄÄÒ»½×¶ÎÅ×´íһĿÁËÈ»
- function connect() {
- printl("[INFO] ÕýÔÚÁ¬½Ó MQTT Broker: " + CFG.brokerUrl);
- if (!CFG.clientId) {
- CFG.clientId = generateClientId();
- }
- printl("[INFO] ¿Í»§¶Ë ID: " + CFG.clientId);
- // ---- ½×¶Î1£º´´½¨ MqttClient£¨¹¹ÔìÆ÷ÀïÓÐ log.fine£¬ÊÇ NPE ¸ß·¢µã£© ----
- try {
- var persistence = new MemoryPersistence();
- var brokerUri = CFG.brokerUrl;
- if (brokerUri.indexOf("://") < 0) {
- brokerUri = "tcp://" + brokerUri;
- }
- G.mqttClient = new MqttClient(brokerUri, CFG.clientId, persistence);
- printl("[INFO] [½×¶Î1/3] MqttClient ´´½¨³É¹¦");
- } catch (e1) {
- G.connected = false;
- logConnErr("½×¶Î1 ´´½¨MqttClient", e1);
- return false;
- }
- // ---- ½×¶Î2£ºÅäÖÃÁ¬½ÓÑ¡Ïî ----
- var options = null;
- try {
- options = new MqttConnectOptions();
- options.setKeepAliveInterval(CFG.keepAliveSec);
- options.setConnectionTimeout(CFG.connectTimeoutSec);
- options.setCleanSession(CFG.cleanSession);
- if (CFG.autoReconnect) {
- options.setAutomaticReconnect(true);
- try {
- options.setMaxReconnectDelay(CFG.maxReconnectDelayMs);
- } catch (e) {}
- }
- if (CFG.username) {
- options.setUserName(CFG.username);
- }
- if (CFG.password) {
- options.setPassword(CFG.password.toCharArray());
- }
- if (CFG.willTopic && CFG.willMessage) {
- options.setWill(
- CFG.willTopic,
- new java.lang.String(CFG.willMessage).getBytes("UTF-8"),
- CFG.willQos,
- CFG.willRetained
- );
- }
- printl("[INFO] [½×¶Î2/3] Á¬½ÓÑ¡ÏîÅäÖÃÍê³É");
- } catch (e2) {
- G.connected = false;
- logConnErr("½×¶Î2 ÅäÖÃÑ¡Ïî", e2);
- return false;
- }
- // ---- ½×¶Î3£ºÉèÖûص÷²¢Ö´ÐÐÁ¬½Ó£¨ÍøÂçÎÕÊÖÔÚÕâÀ ----
- try {
- G.mqttClient.setCallback(createMqttCallback());
- G.mqttClient.connect(options);
- G.connected = true;
- G.reconnectCount = 0;
- printl("[INFO] [½×¶Î3/3] MQTT Á¬½Ó³É¹¦ ¡ª ÎÕÊÖÍê³É");
- try { subscribeTopics(); } catch (eS) { printl("[WARN] ¶©ÔÄÒì³£: " + eS.message); }
- try {
- publish(getPubTopic("online"), {
- clientId: CFG.clientId,
- device: getDeviceInfo(),
- ts: nowSec()
- }, 0);
- } catch (eP) { printl("[WARN] ÉÏÏßÏûÏ¢·¢²¼Òì³£: " + eP.message); }
- return true;
- } catch (e3) {
- G.connected = false;
- logConnErr("½×¶Î3 Ö´ÐÐÁ¬½Ó", e3);
- return false;
- }
- }
- // ========== ¶Ï¿ªÁ¬½Ó ==========
- function disconnect() {
- if (G.mqttClient) {
- try {
- if (G.connected) {
- publish(getPubTopic("offline"), {
- clientId: CFG.clientId,
- ts: nowSec()
- }, 0);
- }
- G.mqttClient.disconnect();
- printl("[INFO] ÒѶϿª MQTT Á¬½Ó");
- } catch (e) {
- printl("[WARN] ¶Ï¿ªÒì³£: " + e.message);
- }
- }
- G.connected = false;
- }
- // ========== ¹Ø±ÕÇåÀí ==========
- function cleanup() {
- G.running = false;
- disconnect();
- try {
- if (G.mqttClient) {
- G.mqttClient.close(true);
- }
- } catch (e) {}
- printl("[INFO] ×ÊÔ´ÒÑÇåÀí");
- }
- // ========== Ö÷³ÌÐò ==========
- function main() {
- try {
- G.startTime = nowSec();
- printl("[INFO] ==========================================");
- printl("[INFO] MQTT ¿Í»§¶Ë (Eclipse Paho) Æô¶¯");
- printl("[INFO] Broker: " + CFG.brokerUrl);
- printl("[INFO] ClientID: " + (CFG.clientId || "×Ô¶¯Éú³É"));
- printl("[INFO] ÐÄÌø: " + CFG.keepAliveSec + "s");
- printl("[INFO] ×Ô¶¯ÖØÁ¬: " + CFG.autoReconnect);
- printl("[INFO] CleanSession: " + CFG.cleanSession);
- printl("[INFO] ¶©ÔÄÖ÷Ìâ: " + CFG.subscribeTopics.length + " ¸ö");
- printl("[INFO] É豸ÐÅÏ¢: " + JSON.stringify(getDeviceInfo()));
- printl("[INFO] ==========================================");
- if (!connect()) {
- startReconnectLoop();
- }
- var tick = 0;
- (function keepAlive() {
- try {
- if (!G.running) {
- printl("[INFO] Ö÷Ï̱߳£»îÍ˳ö");
- return;
- }
- tick++;
- if (tick % 30 === 0) {
- printl("[INFO] [±£»î] ÒÑÔËÐÐ=" + (nowSec() - G.startTime) +
- "s Á¬½Ó=" + G.connected +
- " ·¢ËÍ=" + G.msgSentCount +
- " ½ÓÊÕ=" + G.msgRecvCount +
- " ÖØÁ¬=" + G.reconnectCount);
- }
- } catch (e) {
- printl("[ERROR] ±£»îÒì³£(ÒѶµ×¡): " + e.message);
- }
- try { setTimeout(keepAlive, 1000); }
- catch (e) {
- try { runTime.setTimeout(keepAlive, 1000); } catch (e2) {}
- }
- })();
- if (CFG.runDuration > 0) {
- sleep.millisecond(CFG.runDuration);
- cleanup();
- }
- } catch (e) {
- printl("[FATAL] Ö÷³ÌÐòÒì³£: " + e.message + "\n" + (e.stack || ""));
- try { cleanup(); } catch (e2) {}
- }
- }
- // ========== ÊÖ¶¯ÖØÁ¬Ñ»· ==========
- function startReconnectLoop() {
- (function reconnectStep() {
- try {
- if (!G.running) return;
- if (G.connected) return;
- G.reconnectCount++;
- printl("[INFO] ÊÖ¶¯ÖØÁ¬³¢ÊÔ " + G.reconnectCount);
- if (connect()) {
- printl("[INFO] ÊÖ¶¯ÖØÁ¬³É¹¦");
- return;
- }
- setTimeout(reconnectStep, CFG.reconnectDelayMs);
- } catch (e) {
- printl("[ERROR] ÖØÁ¬Òì³£(ÒѶµ×¡): " + e.message);
- setTimeout(reconnectStep, CFG.reconnectDelayMs);
- }
- })();
- }
- // ========== Æô¶¯ ==========
- main();
¸´ÖÆ´úÂë
|
|