1、下载EMQ安装包,配置EMQ环境
本文以Windows为例 如图,选择对应的系统和版本
2、解压 cmd进入bin文件夹
输入 emqx start 启动服务,打卡浏览器输入本地ip:18083
进入登录页面 默认用户名密码 admin/public
至此MQTT服务已启动成功。
3、搭建SpringBoot项目
application.yml配文件:
#MQTT Config
mqtt:
#MQTT-服务器连接地址,如果有多个,用逗号隔开,如:tcp://127.0.0.1:61613,tcp://192.168.2.133:61613
host: tcp://127.0.0.1:1883
#MQTT-连接服务器默认客户端ID
clientid: mqtt_id
#MQTT-用户名
username: admin
#MQTT-密码
password: admin
#MQTT-默认的消息推送主题,实际可在调用接口时指定
topic: test
#连接超时
timeout: 1000
#设置会话心跳时间
keepalive: 100
pom.xml
<!-- mqtt -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Component
@Configuration
@ConfigurationProperties(MqttConfiguration.PREFIX)
public class MqttConfiguration {
@Autowired
private MqttPushClient mqttPushClient;
public static final String PREFIX="mqtt";
private String host;
private String clientid;
private String username;
private String password;
private String topic;
private int timeout;
private int keepalive;
@Bean
public MqttPushClient getMqttPushClient() {
mqttPushClient.connect(host, clientid, username, password, timeout,keepalive);
// 以/#结尾表示订阅所有以test开头的主题
mqttPushClient.subscribe("test/#", 0);
return mqttPushClient;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getClientid() {
return clientid;
}
public void setClientid(String clientid) {
this.clientid = clientid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getKeepalive() {
return keepalive;
}
public void setKeepalive(int keepalive) {
this.keepalive = keepalive;
}
}
消费者监听
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.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @Classname PushCallback
* @Description 消费监听类
*/
@Component
public class PushCallback implements MqttCallback {
@Autowired
private MqttConfiguration mqttConfiguration;
private static MqttClient client;
@Override
public void connectionLost(Throwable throwable) {if (client == null || !client.isConnected()) {
System.out.println("连接断开,正在重连....");
mqttConfiguration.getMqttPushClient();
}
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("接收消息主题 : " + topic);
System.out.println("接收消息Qos : " + message.getQos());
System.out.println("接收消息内容 : " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("deliveryComplete---------" + token.isComplete());
}
}
重点来了,如何确定设备上下线呢?
想了好几个方案:
①:遗嘱机制
②:主题设计
③:EMQX 系统主题 ,需要修改服务配置文件
④:EMQX .Hook插件 桥接到网关服务
⑤:EMQ商业版 EMQX Enterprise
⑥:获取连到服务器的设备信息,通过状态来判断,缺点无法实时刷新状态且频繁调用接口对服务器压力大
最终选择 ③:EMQX 系统主题 ,需要修改服务配置文件
emqx\etc\acl.config
添加 {allow, all, subscribe, ["$SYS/brokers/+/clients/#"]}.
重启服务或者重新加载
$ ./bin/emqx_ctl acl reload
模拟设备上线:
模拟设备下线:
完。