MQTT介绍
首先,我们简单的提一下mqtt是什么;MQTT(Message Queuing Telemetry
Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。
上面的这些语言都太官方了,我觉得总结一句话就是:连上mqtt之后,服务器那边就可以在你不断的情况下给你推送数据,并且实时性比较好;
工作原理
现在就让我们来总结一下我们所使用的mqtt到底是怎么工作的,方便以后查阅的时候少走弯路。
流程图:
一、既然要使用官方提供的mqtt协议,那么就必须导入官方给出的jar包我们使用的是IBM公司提供的wmqtt.jar包。
二、既然要让它一直在后台运行,则必须通过服务来运行,后台常驻才符合我们的要求。
既然是链接前后台的服务器,那么链接的状态可能要分很多种,例如:
就会有以上的六种状态信息;链接的状态是通过发送广播的形式发送的:
(1)、断开链接的广播:
(2)、尝试链接,但未链接上:
(3)、链接断开,重新链接:
(4)、由于其他的原因导致无法链接:
(5)、链接成功:
(6)、未能链接上:
每一种链接的状态都会发送相应的状态信息,在log中打印出来,让我们很直观的看到此时的mqtt处于哪一种状态。
三、我们在链接mqtt的时候需要先定义一个链接的接口:
mqttClient = MqttClient.createMqttClient(mqttConnSpec,usePersistence);
String mqttConnSpec = "tcp://" + brokerHostName + "@"+ brokerPortNumber;
详细信息是:“tcp://ip@1883”;
private boolean connectToBroker()这个方法是判断当前的链接是否存在,存在返回true,不存在返回false,然后在执行后面的操作;
// try to connect
mqttClient.connect(generateClientId(), cleanStart, keepAliveSeconds);
此时才是mqtt建立链接的操作,第一个参数generateClientID()是建立链接的一个关键字,是为了区分不同的主机链接到mqtt,方便服务器那边进行区分。(“fiber1/Android手机自带的序列号,这个码是唯一的,每一部手机都是不一样的,这样才能更好的区分)。第二个参数是false。第三个参数是保持心跳,五秒一次。
上面就已经说过了,当它返回的是true的时候,就说明这个链接已经建立成功了,后续的操作就是订阅我们的主题了;
mqttClient.subscribe(topics, parms);
既然有订阅,那么就必须有取消订阅,因为取消订阅是为了让我们的设备在注销之后,不想再收到任何的消息,或者是删除设备之后不想再收到任何的消息是一样的道理。所以这个操作是必不可少的。
mqttClient.unsubscribe(topics);
取消订阅和订阅的区别就在于订阅的时候需要发送QoS,而取消订阅的时候是不需要发送QoS的;
四、下面的就是接受广播:
1、private class BackgroundDataChangeIntentReceiver extends BroadcastReceiver// 接收广播
我们在做这件事的时候,通过请求一个唤醒锁,我们要求尽可能的唤醒锁-只是足够维持处理器的运行,直到我们完成
2、private class NetworkConnectionIntentReceiver extends BroadcastReceiver
所谓的响应于网络连接的变化-在连接到服务器之后,这让我们等待,直到我们有一个可用的数据连接
3、public class PingSender extends BroadcastReceiver
这个广播用于唤醒手机,使手机可以时刻接收mqtt的推送消息;
4、public class StatusUpdateReceiver extends BroadcastReceiver
当mqtt的客户端连接的状态发生改变的时候,通过StatusUpdateReceiver接收广播;
5、public class MQTTMessageReceiver extends BroadcastReceiver
当收到mqtt的推送的消息时,通过MQTTMessageReceiver接收广播;
五、最后就是,当我们收到推送的消息,怎么处理?比如下面的处理上报的告警消息
通过异步任务,将获取的json数据进行解析,
public static class AlarmTask extends AsyncTask// 收到告警消息,插入数据库,并且弹出提示界面.
alarmData = jsonobj.geMYSYString("alarm");
......告警处理代码
注意:在网络断开之后,我们没有重连的机制,只有在网络重新链接上之后,我们才会去再链接mqtt(重连的机制还是和第一次链接的机制一致),断网时,我们也没有必要去链接,因为这本身就是不通的,一直链接,反而会造成阻塞;