使用MQTT协议往Android手机推送消息

最近做了一些IoT相关的工作,对于MQTT协议用得比较多。MQTT诞生较早(1999年)但是一直不温不火,直到最近由于物联网的兴起,才由IBM在2013年将其提交到了OASIS规范中,从而在物联网的协议中占得一席之地。这个协议有着如下特点:

轻量化,消息头部采用二进制格式

订阅/发布模式,这样非常适合于服务器推送

可以对不同的话题采用不同的QoS(服务质量),可以在可靠性和复杂度之间取得平衡

介于之前一直想做一个往自己Android手机上推送消息的小应用。但是因为某些网络环境的原因你懂的,Google为Android设计的推送机制在国内并不能很好的使用。如果使用类似于Rest API轮询的方式,对于移动设备来说过于耗费电量以及流量,并不是很好的方法。了解到有了MQTT这种轻量级的协议以后,发现完美契合这个推送消息的需求。于是赶紧试一试!

在整个流程中,需要3个点,分别是MQTT Broker,推送消息的client,以及接收消息的Android client。

1. MQTT Broker
就是一个接受订阅,接受并转发消息的服务器。我选择基于Node的项目mosca,由于我是独立使用,所以特别简单。

 npm install mosca pino -g
mosca -v | pino

简直不要太方便!70

查看一下网络端口

 tcp6       0      0 :::1883                 :::*                    LISTEN

好,已经默认监听在1883端口了。

2. 推送消息的client
就是要推送消息的消息源。这个还是用Node的MQTT项目(Node的库真是好用哭)。
同样是两种用法,第一种独立使用:

 npm install mqtt -g
mqtt sub -t 'topic' -h 'broker_url' -v
mqtt pub -t 'topic' -h 'broker_url' -m 'message'

第二种嵌入code:
[javascript]
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://test.mosquitto.org')

client.on('connect', function () {
client.subscribe('presence')
client.publish('presence', 'Hello mqtt')
})

client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
client.end()
})
[/javascript]

3. 接收消息的Android client
这个比前两个找起来难度大点。在Play市场上搜索MQTT,试了一些排名靠前的应用,发现对于MQTT的支持都没有什么问题,收发消息也都正常。但是都无法支持后台保持连接以及消息提醒机制。最后找到了这么一个应用,可以实现MQTT消息的后台以及息屏提醒,叫做Linear MQTT Dashboard

打开应用 先进行一下简单的设置
1

返回到主界面,可以看到有两个状态指示灯
2
第二个就表示MQTT Broker的连接状态,如果是绿色的就说明已经成功连接上了。

然后增加一个widget来显示消息,先按一下上图中的暂停按钮,然后按加号添加一个widget,其中主要填好Sub.topic就可以了

我们试着从另一个地方往test话题推送一条消息

 
mqtt pub -t 'test' -h '[MQTT_BROKER_URL]' -m 'hello world'

3
接收成功,那么看看如果app切到后台能不能收到提醒呢
4
可以看到,成功在通知栏提醒了消息,并且有震动。在息屏时也会有震动提醒,完美!

那么到此为止,就利用MQTT协议成功的进行了从任意client往Android手机推送消息的机制,而且非常省电和省流量。其实在这个方案中,Android手机不仅可以作为消息的接收端,也可以作为消息的发送端,那么如果把接收端放在一些嵌入式设备或者小型开发板上(由于MQTT是物联网的标准协议,所以支持较为广泛),那么就可以通过手机来控制这些设备,进而实现智能家居等等任何你能想象的功能!