最近项目中需要用到MQTT协议,于是上网看了很多资料,照葫芦画瓢写了一个简单的Demo,将过程记录在此。
Mqtt是一个轻量级的消息传输协议,使用发布/订阅消息模式,使用起来非常方便。
在开始敲代码之前,我们先把一些环境和工具装好,以便后续使用。
1. windows下搭建mqtt服务器
我选择的是搭建一个Apollo服务器,可以参考【MQTT】在Windows下搭建MQTT服务器 这篇博文,介绍得很详细。
1) 搭建JAVA环境,并配置好JAVA_HOME环境变量
2) 下载Apollo服务器文件并解压:官网下载
3)CMD环境下运行bin\apollo.cmd create mybroker
,建立名为mybroker的实例,用户名和密码默认为admin-password
4)进入\mybroker\bin
目录下,执行apollo-broker.cmd run
5)运行后可以通过浏览器访问https://127.0.0.1:61681/
进入web后台管理页面
2.下载Eclipse Paho MQTT Utility
Eclipse Paho MQTT Utility是一个很实用的mqtt工具,点此进入官网下载
界面很友好,使用起来比较简单,教程连接:
https://jingyan.baidu.com/article/25648fc16b8e969191fd00be.html
使用Android Studio建立一个MqttDemo工程,在build.gradle中添加
repositories {
maven {
url "https://repo.eclipse.org/content/repositories/paho-releases/"
}
dependencies {
...
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
}
添加权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
注册mqtt服务
<service android:name="org.eclipse.paho.android.service.MqttService" />
这里我们新建一个MqttManager类,该类主要提供建立mqtt连接、发布消息、订阅消息、接收消息等方法。
import android.content.Context;
import android.util.Log;
import android.webkit.WebMessagePort;
import org.eclipse.paho.android.service.MqttAndroidClient;
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.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class MqttManager {
public static final String TAG = MqttManager.class.getSimpleName();
private String host = "tcp://192.168.232.204:61613";
private String userName = "admin";
private String passWord = "password";
private String clientId = "";
private static MqttManager mqttManager = null;
private MqttClient client;
private MqttConnectOptions connectOptions;
public MqttManager(Context context){
clientId = MqttClient.generateClientId();
}
public MqttManager getInstance(Context context){
if(mqttManager == null){
mqttManager = new MqttManager(context);
}else{
return mqttManager;
}
return null;
}
public void connect(){
try{
client = new MqttClient(host,clientId,new MemoryPersistence());
connectOptions = new MqttConnectOptions();
connectOptions.setUserName(userName);
connectOptions.setPassword(passWord.toCharArray());
client.setCallback(mqttCallback);
client.connect(connectOptions);
}catch (MqttException e){
e.printStackTrace();
}
}
public void subscribe(String topic,int qos){
if(client != null){
int[] Qos = {qos};
String[] topic1 = {topic};
try {
client.subscribe(topic1, Qos);
Log.d(TAG,"订阅topic : "+topic);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
public void publish(String topic,String msg,boolean isRetained,int qos) {
try {
if (client!=null) {
MqttMessage message = new MqttMessage();
message.setQos(qos);
message.setRetained(isRetained);
message.setPayload(msg.getBytes());
client.publish(topic, message);
}
} catch (MqttPersistenceException e) {
e.printStackTrace();
} catch (MqttException e) {
e.printStackTrace();
}
}
private MqttCallback mqttCallback = new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
Log.i(TAG,"connection lost");
}
@Override
public void messageArrived(String topic, MqttMessage message){
Log.i(TAG,"received topic : " + topic);
String payload = new String(message.getPayload());
Log.i(TAG,"received msg : " + payload);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.i(TAG,"deliveryComplete");
}
};
}
这里host就是前面搭建的mqtt服务器的IP地址和端口,userName和passWord则是默认的。clientId是mqtt客户端的唯一标识符,如果网络中有多个客户端,可以通过clientId来辨别。这里使用generateClientId方法自动生成id。
当然,这个类只能简单地测试消息订阅和收发,还需要后续完善。
接下来在MainActivity添加使用MqttManager的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mqttManager = new com.test.mqttdemo.MqttManager(this);
mqttManager.connect();
mqttManager.subscribe("/testSubscribe",0);
mqttManager.publish("/testPublish","hello mqtt",false,0);
setContentView(R.layout.activity_main);
}
app启动后即会订阅/testSubscribe
主题,并发布以/testPublish
为topic,hello mqtt
为payload的消息。
怎么测试程序是否收发成功了呢?我们在Eclipse Paho MQTT Utility中新建一个连接,服务器url与代码中一样:tcp://192.168.232.204:61613
,这时运行我们的程序,右边的历史记录框中会显示接收到消息。
再通过发布一个主题为/testSubscribe
的消息,在Android Studio的Logcat中即可看到输出的消息主题和内容。
至此,一个简单的mqtt消息收发程序就完成了。