2017-01-02 57 views
1

在我當前的項目中,我使用基於MQTT本地代理的實施和設置,使用this link。本地基於經紀人的MQTT實施工作正常。使用Android應用程序的基於本地經紀人(MQTT)的發佈/訂閱

在最初,我使用Node.js的發佈者和用戶使用此本地代理,以使信息的交流和它的作品沒有互聯網連接也(因爲這些設備都連接到同一網絡,本地券商MQTT基於API實施如http://192.168.0.105)。

現在,我想用Android應用程序替換Node.js訂戶。我的android應用程序使用mqtt paho庫進行通信並使用mqtt API mqtt://test.mosquitto.org:1883。如果我正在使用mqtt開放代理,即比Node.js發佈者和Android應用程序訂閱者都更加安全(這種情況是使用API​​ mqtt://test.mosquitto.org:1883討論基於mosquitto的mqtt實現)。

現在,我想在Android應用程序中使用基於本地代理的實現。所以我必須用http://192.168.0.105代替mqtt://test.mosquitto.org:1883 API,因爲我想使用基於本地代理的mqtt實現。當我在android代碼中使用http://192.168.0.105 API並將其部署到移動設備時,它顯示錯誤不幸的是,Android應用程序在andoid應用程序中停止了

如何在android應用程序中使用基於本地代理的實現?

此外還分享了Node.js發佈者和訂閱者的代碼。 Node.js的發佈者(本地代理基於實現)

var mqtt = require('mqtt'); 
var client = mqtt.connect('http://192.168.0.105'); 
setInterval(function() { 
var data = { 
    "tempValue" : Math.random(), 
    "unitOfMeasurement" : 'C' 
    }; 
client.publish('tempMeasurement', JSON.stringify(data)); 
}, 5000); 

Node.js的用戶(本地代理基於實現)MQTT用戶的更多,更清晰

var mqtt = require('mqtt'); 
var client = mqtt.connect('http://192.168.0.105'); 
client.subscribe('tempMeasurement'); 
client.on('message', function(topic, payload) { 
     if (topic.toString() == "tempMeasurement") { 
     console.log("Mesage Received "+ payload.toString()); 
    }  
}); 

共享代碼:

package iotsuite.pubsubmiddleware; 

import org.eclipse.paho.client.mqttv3.MqttClient; 
import org.eclipse.paho.client.mqttv3.MqttException; 
import org.eclipse.paho.client.mqttv3.internal.MemoryPersistence; 

public class MQTTSubscriber { 

// URI for open MQTT broker 
// public static final String BROKER_URL = "tcp://test.mosquitto.org:1883"; 
public static final String BROKER_URL = "mqtt://192.168.0.105"; 

private MqttClient client; 

public MQTTSubscriber(PubSubMiddleware pubsub) { 
    try { 
     client = new MqttClient(BROKER_URL, MqttClient.generateClientId(), 
       new MemoryPersistence()); 

     client.setCallback(new PushCallback(pubsub)); 
     client.connect(); 

    } catch (MqttException e) { 
     e.printStackTrace(); 
    } 
} 

public void subscribe(String topicName) throws MqttException { 

    client.subscribe(topicName); 

    System.out.println("Subscribed. Topic: " + topicName); 
} 

} 

並訂閱tempMeasurement使用以下代碼:

package framework; 

import iotsuite.common.Logger; 
import iotsuite.pubsubmiddleware.PubSubMiddleware; 
import iotsuite.pubsubmiddleware.Subscriber; 
import iotsuite.semanticmodel.Device; 
import android.util.Log; 
import com.google.gson.Gson; 
import com.google.gson.JsonObject; 
import com.google.gson.JsonParser; 

public abstract class SmartHomeApp implements Runnable, Subscriber { 

protected final PubSubMiddleware myPubSubMiddleware; 
protected final Device myDeviceInfo; 
Gson gson = new Gson(); 

public SmartHomeApp(PubSubMiddleware pubSubM, Device deviceInfo) { 

    this.myPubSubMiddleware = pubSubM; 
    this.myDeviceInfo = deviceInfo; 
    postInitialize(); 

} 

protected void postInitialize() { 
    subscribeDisplayTemp(); 

} 

@Override 
public void notifyReceived(String eventName, Object arg) { 
    try { 

     if (eventName.equals("tempMeasurement")) { 
      Logger.log(myDeviceInfo.getName(), "TempMonitoringApp", 
        "Notification Received tempMeasurement "); 
      JsonObject jsonObject = new JsonParser().parse(arg.toString()) 
        .getAsJsonObject(); 
      double tempValue = jsonObject.get("tempValue").getAsDouble(); 
      // double yahootempValue = 
      // jsonObject.get("yahootempValue").getAsDouble(); 
      TempStruct tempStruct = new TempStruct(tempValue, "C"); 
      System.out.println("tempValue is " + tempValue 
        + " in framework"); 
      Log.i("tempValue", "tempValue is received in framework"); 
      onNewDisplayTempNotify(tempStruct); 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
public void run() { 
} 

public abstract void onNewDisplayTempNotify(TempStruct arg); 

public void subscribeDisplayTemp() { 

    this.myPubSubMiddleware.subscribe(this, "tempMeasurement"); 
} 

} 

使用上面的代碼,我想顯示從Node.js代碼接收到的tempValue到Android應用程序。來自Android的錯誤如下:

01-04 23:03:26.786: E/AndroidRuntime(21793): FATAL EXCEPTION: main 
01-04 23:03:26.786: E/AndroidRuntime(21793): Process: com.example.android,  PID: 21793 
01-04 23:03:26.786: E/AndroidRuntime(21793): java.lang.RuntimeException: Unable to start activity   ComponentInfo{com.example.android/com.example.android.MainActivity}:  java.lang.IllegalArgumentException 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.ActivityThread.-wrap11(ActivityThread.java) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.os.Handler.dispatchMessage(Handler.java:102) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.os.Looper.loop(Looper.java:148) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.ActivityThread.main(ActivityThread.java:5443) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at java.lang.reflect.Method.invoke(Native Method) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
01-04 23:03:26.786: E/AndroidRuntime(21793): Caused by: java.lang.IllegalArgumentException 
01-04 23:03:26.786: E/AndroidRuntime(21793): at org.eclipse.paho.client.mqttv3.MqttClient.validateURI(MqttClient.java:204) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:175) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at iotsuite.pubsubmiddleware.MQTTPublisher.<init>(MQTTPublisher.java:21) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at iotsuite.pubsubmiddleware.PubSubMiddleware.<init>(PubSubMiddleware.java:58) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at  iotsuite.pubsubmiddleware.IoTSuiteFactory.getInstance(IoTSuiteFactory.java:16) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at sim.deviceD9.Startup.setUpNode(Startup.java:25) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at sim.deviceD9.Startup.startDevice(Startup.java:63) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at com.example.android.MainActivity.onCreate(MainActivity.java:21) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.Activity.performCreate(Activity.java:6259) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130) 
01-04 23:03:26.786: E/AndroidRuntime(21793): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379) 
01-04 23:03:26.786: E/AndroidRuntime(21793): ... 9 more 
+0

試着用'MQTT:// 192.168.0.103'而不是'http' –

+1

嘗試將'BROKER_URL'改爲'tcp://192.168.0.105:1883' – hardillb

+0

@ hardillb-感謝您的迅速反應。它正在工作。您能否將此作爲答案? –

回答

1

問題是您的URI使用的是http://方案。 http://用於連接到HTTP服務器而不是MQTT代理。

您需要使用tcp:// URI爲Android(這可能爲工作的NodeJS爲好,但肯定mqtt://工程的NodeJS

mqtt://192.168.0.105

var mqtt = require('mqtt'); 
var client = mqtt.connect('mqtt://192.168.0.105'); 
setInterval(function() { 
var data = { 
    "tempValue" : Math.random(), 
    "unitOfMeasurement" : 'C' 
    }; 
client.publish('tempMeasurement', JSON.stringify(data)); 
}, 5000); 
+0

再次出現同樣的問題Android應用程序。它部署到Android手機,我無法打開應用程序,它顯示錯誤不幸的是,Android應用程序已停止。我錯過了什麼嗎? –

+1

沒有看到整個堆棧跟蹤,這是不可能的。編輯問題以包含錯誤消息(全部) – hardillb

+0

@ hardillb-我將盡快更新整個堆棧跟蹤的問題。 –