ruoyi整合mqtt
ruoyi整合mqtt
mqtt
报错客户机未连接32104,可能是没连接上,也可能是两个客户端clientID相同,也可能是同一台机子subscribe(Topic,Qos)订阅了多次
在消费时,需要对方的通道有发送测试信息,我们才能取出来消费,消费完出队。
本地测试:
https://mqttx.app/zh
下载MQTTX测试工具,创建新连接,创建订阅。
将配置文件中的信息对应填写,编写java代码启动项目;
在MQTTX中的发送窗口中,选好对应topic,写入json发送。
看到控制台有log输出则成功;
导入依赖
<!-- 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>
配置
mqtt: username: admin password: admin host-url: tcp://broker.emqx.io:1883 # 服务器的地址和端口,这个需要改 clientID: test1000 # 这个改不改随意,但不同的客户端肯定不能一样 default-topic: testtopic/1 # 默认主题 timeout: 100 keepalive: 100
package com.ruoyi.web.controller.Mqtt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; /** * @Classname MqttConfig * @Description mqtt相关配置信息 * @Date 2020/3/5 11:00 * @Created by bam */ @Component @ConfigurationProperties("spring.mqtt") public class MqttConfig { @Autowired private MqttPushClient mqttPushClient; /** * 用户名 */ // @Value("username") private String username; /** * 密码 */ private String password; /** * 连接地址 */ private String hostUrl; /** * 客户Id */ private String clientID; /** * 默认连接话题 */ private String defaultTopic; /** * 超时时间 */ private int timeout; /** * 保持连接数 */ private int keepalive; @Bean public MqttPushClient getMqttPushClient() { // System.out.println("hostUrl: "+ hostUrl); // System.out.println("clientID: "+ clientID); // System.out.println("username: "+ username); // System.out.println("password: "+ password); // System.out.println("timeout: "+timeout); // System.out.println("keepalive: "+ keepalive); mqttPushClient.connect(hostUrl, clientID, username, password, timeout, keepalive); System.out.println("MQTT服务启动成功"); // 以/#结尾表示订阅所有以test开头的主题 mqttPushClient.subscribe(defaultTopic, 0); return mqttPushClient; } public void setMqttPushClient(MqttPushClient mqttPushClient) { this.mqttPushClient = mqttPushClient; } 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 getHostUrl() { return hostUrl; } public void setHostUrl(String hostUrl) { this.hostUrl = hostUrl; } public String getClientID() { return clientID; } public void setClientID(String clientID) { this.clientID = clientID; } public String getDefaultTopic() { return defaultTopic; } public void setDefaultTopic(String defaultTopic) { this.defaultTopic = defaultTopic; } 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; } }
package com.ruoyi.web.controller.Mqtt; import org.eclipse.paho.client.mqttv3.*; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;
import com.ruoyi.web.controller.Mqtt.MqttPushClient;
/** * * @author bam * 2020年3月5日 * MqttPushClient.java * */ @Component public class MqttPushClient { private static final Logger logger = LoggerFactory.getLogger(com.ruoyi.web.controller.Mqtt.MqttPushClient.class); @Autowired private com.ruoyi.web.controller.Mqtt.PushCallback pushCallback; @Value("${spring.mqtt.default-topic}") private String topic ; private static MqttClient client; private static MqttClient getClient() { return client; } private static void setClient(MqttClient client) { com.ruoyi.web.controller.Mqtt.MqttPushClient.client = client; } /** * 客户端连接 * * @param host ip+端口 * @param clientID 客户端Id * @param username 用户名 * @param password 密码 * @param timeout 超时时间 * @param keepalive 保留数 */ public void connect(String host, String clientID, String username, String password, int timeout, int keepalive) { MqttClient client; try { client = new MqttClient(host, clientID, new MemoryPersistence()); MqttConnectOptions options = new MqttConnectOptions(); options.setAutomaticReconnect(true); options.setCleanSession(true); options.setUserName(username); options.setPassword(password.toCharArray()); options.setConnectionTimeout(timeout); options.setKeepAliveInterval(keepalive); com.ruoyi.web.controller.Mqtt.MqttPushClient.setClient(client); subscribe(topic,2); try { client.setCallback(pushCallback); client.connect(options); } catch (Exception e) { try { client.reconnect(); }catch (Exception e1){ e1.printStackTrace(); } e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } /** * 发布 * * @param qos 连接方式 * @param retained 是否保留 * @param topic 主题 * @param pushMessage 消息体 */ public void publish(int qos, boolean retained, String topic, String pushMessage) { MqttMessage message = new MqttMessage(); message.setQos(qos); message.setRetained(retained); message.setPayload(pushMessage.getBytes()); MqttTopic mTopic = MqttPushClient.getClient().getTopic(topic); if (null == mTopic) { logger.error("topic not exist"); } MqttDeliveryToken token; try { logger.info(mTopic.toString()); token = mTopic.publish(message); token.waitForCompletion(); } catch (MqttPersistenceException e) { e.printStackTrace(); } catch (MqttException e) { e.printStackTrace(); } } /** * 订阅某个主题 * * @param topic 主题 * @param qos 连接方式 */ public void subscribe(String topic, int qos) { logger.info("开始订阅主题" + topic); try { MqttPushClient.getClient().subscribe(topic, qos); } catch (MqttException e) { e.printStackTrace(); } } }
package com.ruoyi.web.controller.Mqtt; import com.alibaba.fastjson.JSONObject; import com.ruoyi.web.controller.Mqtt.MqttPushClient; import com.ruoyi.web.controller.Mqtt.MqttConfig; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.ruoyi.common.websocket.*; import javax.annotation.Resource; import java.lang.reflect.Method; /** * @Classname PushCallback * @Description 消费监听类 * @Date 2019/4/11 23:31 * @Created by Jack */ @Component public class PushCallback implements MqttCallback { private static final Logger logger = LoggerFactory.getLogger(MqttPushClient.class); @Autowired private MqttConfig mqttConfig; private static MqttClient client; @Resource private WebSocket webSocket; @Override public void connectionLost(Throwable throwable) { // 连接丢失后,一般在这里面进行重连 logger.info("连接断开,可以做重连"); if (null != client) { mqttConfig.getMqttPushClient(); } } @Override public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception { // subscribe后得到的消息会执行到这里面 logger.info("接收消息主题 : " + topic); logger.info("接收消息Qos : " + mqttMessage.getQos()); logger.info("接收消息内容 : " + new String(mqttMessage.getPayload())); String msg= new String(mqttMessage.getPayload()); String data = JSONObject.parseObject(msg).getString("data"); // webSocket.sendMessage(data); } @Override public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { logger.info("消息发送成功---------" + iMqttDeliveryToken.isComplete()); } }