Sto creando un semplice client MQTT per Android e sto ricevendo l'errore "Errore socket per identificativo cliente" nella console RMBS. Questo accade solo nell'implementazione Android del client (ho anche creato un client desktop Java e viene eseguito senza problemi). Per il client Android, sto citando in giudizio le librerie client Java di Paho. Qui è il mio codice:Errore socket per identificatore client su broker MQTT RSMB quando si utilizza Android
Questo è il client Android:
package com.example.mqttdroid;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.internal.MemoryPersistence;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;
public class MQTTClient extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mqttclient);
// new BackTask().execute(); not used because (seems to be the problem)
MqttConnectOptions conOpts = new MqttConnectOptions();
conOpts.setKeepAliveInterval(30);
conOpts.setWill(client.getTopic("Error"), "something bad happened".getBytes(), 1, true);
client.connect(conOpts);
client.subscribe("/House/Kitchen/Bulb");
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable arg0) {
// TODO Auto-generated method stub
}
@Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
// TODO Auto-generated method stub
}
@Override
public void messageArrived(String arg0, MqttMessage arg1)
throws Exception {
// TODO Auto-generated method stub
Toast.makeText(Main.this, arg0.toString(), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.mqttclient, menu);
return true;
}
/*public class BackTask extends AsyncTask<Void, Void, Void>{
private MqttClient client;
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
client = new MqttClient("tcp://"Ip of machine running RSMB":1883", "ANDROID1", new MemoryPersistence());
client.connect();
client.subscribe("House/Kitchen/Bulb");
} catch (MqttException e) {
// TODO Auto-generated catch block
Log.e("ERROR", "NOT CONNECTED");
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
try {
client.setCallback(new MqttCallback() {
@Override
public void messageArrived(MqttTopic arg0, MqttMessage arg1)
throws Exception {
// TODO Auto-generated method stub
Toast.makeText(MQTTClient.this, arg0.toString(), Toast.LENGTH_SHORT).show();
}
@Override
public void deliveryComplete(MqttDeliveryToken arg0) {
// TODO Auto-generated method stub
}
@Override
public void connectionLost(Throwable arg0) {
// TODO Auto-generated method stub
}
});
} catch (MqttException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}*/
Questo è il client desktop Java:
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.internal.MemoryPersistence;
public class MQTTBaseClass {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MqttClientPersistence persistence;
try {
MqttClient client = new MqttClient("tcp://localhost:1883", "PC",new MemoryPersistence());
MqttConnectOptions conOpts = new MqttConnectOptions();
conOpts.setKeepAliveInterval(30);
conOpts.setWill(client.getTopic("Error"), "something bad happened".getBytes(), 1, true);
client.connect(conOpts);
MqttMessage msg = new MqttMessage("hello".getBytes());
msg.setQos(0);
msg.setRetained(true);
MqttTopic topic = client.getTopic("House/Kitchen/Bulb");
client.subscribe("House/Kitchen/Bulb");
try {
client.setCallback(new MqttCallback() {
@Override
public void messageArrived(MqttTopic arg0, MqttMessage arg1)
throws Exception {
// TODO Auto-generated method stub
System.out.println(arg1.toString());
}
@Override
public void deliveryComplete(MqttDeliveryToken arg0) {
// TODO Auto-generated method stub
}
@Override
public void connectionLost(Throwable arg0) {
// TODO Auto-generated method stub
}
});
} catch (MqttException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
topic.publish(msg);
} catch (MqttPersistenceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MqttException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
A poche note:
sono collegato sul mio dispositivo Android tramite WiFi, e così è il mio desktop quando eseguo il client Java Dekstop.
Il Cliente Java Destop è in esecuzione sulla stessa macchina del RSMB
Il client Java Desktop crea e subscirbes al tema "Casa/Cucina/Bulb" e invia un messaggio con la stringa "Ciao"
Anche il client Android si abbona a "Casa/Cucina/Bulbo" e tenta di visualizzare un Toast con il messaggio ricevuto.
ho addeded il permesso Internet sul manifesto
dispositivo Android Android sembra connettersi al broker bene, ma non appena ho inizializzare il client Java Desktop Service (o il plug-in del client Paho in Eclipse e pubblica un messaggio) Ottengo l'errore menzionato.
Ho eseguito l'applicazione utilizzando l'emulatore sulla stessa macchina su cui è in esecuzione l'RSMB e ottengo lo stesso errore.
Quale potrebbe essere il problema?
UPDATE:
In origine, ho ricevuto un'eccezione "rete sul filo principale", così ho spostato l'operazione di connessione a un AsyncTask. Ora sembra che il client Android sia ancora connesso quando pubblico un messaggio con il client Java (Asynctask avrebbe potuto creare problemi), ma il messaggio MessageArrived() di MqttCallback() non sembra essere chiamato.
UPDATE 2:
sono riuscito a farlo funzionare. Ecco il codice che sto usando ora:
package com.example.mqttphone;
*import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;*
public class Main extends Activity {
protected static String msg;
public MqttClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
client = new MqttClient("tcp://10.1.201.27:1883", "ANDROID1", new MemoryPersistence());
MqttConnectOptions conOpts = new MqttConnectOptions();
conOpts.setKeepAliveInterval(30);
conOpts.setWill(client.getTopic("Error"), "something bad happened".getBytes(), 1, true);
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable arg0) {
// TODO Auto-generated method stub
}
@Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
// TODO Auto-generated method stub
}
@Override
public void messageArrived(String arg0, MqttMessage arg1)
throws Exception {
// TODO Auto-generated method stub
Main.msg = arg1.toString();
Main.this.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(Main.this, msg, Toast.LENGTH_LONG).show();
}
});
Log.e("MESSAGE RECEIVED", arg1.toString());
}
});
client.connect(conOpts);
//MqttMessage msg = new MqttMessage("ANDROID MESSAGE".getBytes());
//client.getTopic("world").publish(msg);
if(client.isConnected()){
client.subscribe("/House/Kitchen/Bulb");
Toast.makeText(this, "CONNECTED", Toast.LENGTH_SHORT).show();
}
} catch (MqttException e) {
// TODO Auto-generated catch block
Log.e("ERROR", "NOT CONNECTED");
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
+1 per condividere la soluzione –
È necessario impostare il callback _before_ the connect(), altrimenti non è garantito il corretto funzionamento. Un esempio di lavoro può essere trovato qui https://github.com/dobermai/android-mqtt-push –
Controlla l'esempio di Dominik per la soluzione. Inoltre, la versione più recente del client Paho Java (non ancora disponibile come versione binaria) presenta miglioramenti che lo rendono più adatto all'uso su Android, sebbene l'API sia un po 'diversa. http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/tag/?id=v0.2.1 –