I am creating a simple MQTT client for android and I get the "Socket Error for client id" error in the RMBS console. This only happens in the client implementation for Android (I also created a Java client desktop and no problem). For the Android client, I am suing the Paho Java client libraries. Here is my code:
This is an Android client:
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(); } } } }*/
This is the Java desktop client:
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(); } } }
Just a few notes:
I connect to my Android device via Wi-Fi and my desktop when I launch the Java Dekstop client.
Destop client for Java runs on the same machine as RSMB
The Java Desktop client creates and subscribes to the topic "Home / Kitchen / Lamp" and sends a message with the string "Hello"
The Android client also subscribes to "Home / Kitchen / Lamp" and tries to display Toast with the received message.
I added internet permission to android manifest
The Android device seems to be great for the broker, but as soon as I initialize the Java Desktop Service client (or the Paho client plug-in in Eclipse and post the message), I get the error mentioned.
I started the application using the emulator on the same computer as RSMB and I get the same error.
What could be the problem?
UPDATE:
I initially got the exception "Network on Main Thread", so I translated the connection operation into AsyncTask. Now it seems that the Android client is still connected when I post a message with the Java client (Asynctask may have been causing problems), but messageArrived () from MqttCallback () does not seem to be called.
UPDATE 2:
I managed to get it to work. Here is the code I'm using now:
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) {