整体介绍
最近公司用到的推送MQTT。不想过多的介绍背景什么的,我就直接讲怎么实现这个功能。
他这个原理长连接,这个不用多讲,用法类似于EventBus,需要先订阅,然后通过topic再发送消息。topic是什么呢?我先来讲讲整体流程:
先连接服务器,要先建立长连接
然后需要订阅topic,连接之后才能订阅topic
最后就是通过topic推送消息,接收消息
一步一步讲:
第一步,与服务器建立连接
先丢代码,然后看注释:
1 | private void initPush() { |
上面的这些参数,我碰到了两个问题。
上面的这些参数,我碰到了两个问题。
上面的这些参数,我碰到了两个问题。
- 第一个问题,与服务器建立连接,你得先有一个服务器吧?我根据网上的步骤,创建了一个apache-apollo服务器,并且启动了,也启动成功了,我建立连接的时候,总是失败。然后,找啊找,找啊找。问题没有解决,但是,我找到了一个可以用的服务器,也就是这里的uri,不要设置MqttConnectOptions的用户名和密码,设置了他会拒绝
1 | private String host = "tcp://test.mosquitto.org:1883"; |
- 第二个问题,我连接成功之后,不一会,他就会自动断开连接,或者,推送完消息之后,他就会断开连接。然后,网上搜原因,找啊找,诶,我找到了。MqttAndroidClient的构造方法:
1 | /** |
看第三个参数,clientId,指定一个名字,用来连接服务器的身份标识。就是说,你设置的这个值,是你在服务器的唯一标识,不能跟其他用户的相同。我把这个clientId直接用uuid生成,就没问题了。
第二步,订阅topic
回到上面,接着往下面走,
1 | /** |
这个方法就是用来连接服务器的,首先判断是否正在连接,后面那个是判断当前有没有网络。再就是这个iMqttActionListener监听了
1 | // MQTT是否连接成功 |
讷,就是这里,你如果服务器有问题,他一直走onFailure方法。服务器连接成功之后,就是订阅topic。我来说说这个
1 | client.subscribe(myTopic, 0); |
首先,这个主题,是你自己跟服务器商量好的,随便什么都可以。为什么要订阅主题呢?我提前给你瞅瞅推送消息是怎么推送的
第二个参数,消息的类型qos,有三种:0、1、2
- 0代表“至多一次”,消息发布完全依赖底层 TCP/IP 协议。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送
- 1代表“至少一次”,确保消息到达,但消息重复可能会发生
- 2代表“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
简单说明下,如果发送的是临时的消息,例如给某topic所有在线的设备发送一条消息,丢失的话也无所谓,0就可以了。如果需要客户端保证能接收消息,需要指定QoS为1
1 | client.publish(topic, new MqttMessage(msg.getBytes())); |
讷,推送消息,是根据topic推送的,第二个参数,就是你要推送的具体消息。我个人认为,你可以理解成就类似于键值对的形式,
不同的用户可以订阅相同的主题
不同的用户可以订阅相同的主题
不同的用户可以订阅相同的主题
这个就是跟其他长连接不同的地方,底层,其实都一样,虽然我没有看底层的代码。想也想的到,服务器肯定是根据这个主题,去找对应的用户,然后推送消息。而其他的长连接就是直接指定用户。跑题了,跑题了。
第三步,推送、接收消息
当你连接服务器成功之后,就要推送消息了,我用的EventBus发的
1 | private void publishData(String msg) { |
当你的clientId重复的时候,他就会一直走connectionLost方法。到这里,基本上就讲完了,要注意的是,退出的时候,记得要释放资源
1 | @Override |
网上很多都是直接讲整体流程,重来不讲中间碰到的问题。难受