springBoot集成mqtt
springBoot集成mqtt
简介
EMQX是一款大规模可弹性伸缩的云原生分布式物联网 MQTT消息服务器。
作为全球最具扩展性的 MQTT 消息服务器,EMQX 提供了高效可靠海量物联网设备连接,能够高性能实时移动与处理消息和事件流数据,帮助您快速构建关键业务的物联网平台与应用。
下载
https://www.emqx.io/downloads
注意:下载安装后可能会有打不开的情况,此时需要安装Erlang环境。
这里下载安装以windows操作系统为例。
启动
- 进入解压后的bin目录
- 输入cmd进入dos命令窗口,输入 emqx start 命令启动,出现如下说明启动成功
- 访问控制台浏览器输入 http://localhost:18083 即可访问,默认账号密码 admin/public
在控制台可以看到连接的设备相关信息
- 关闭mqtt服务, 在bin目录下 输入 emqx stop 命令。
springBoot集成mqtt
- 导入依赖
<!--mqtt中间件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-integration</artifactId> </dependency> <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: hostUrl: tcp://127.0.0.1:1883 username: guest password: 123456 keepAliveInterval: 60 connectionTimeout: 10 client-id: mqttClient01 server-id: mqttServer01 data-topic: /wvp_ptz will-topic: /will will-content: mqttServer Unexpected disconnection completion-timeout: 10000
- 编写配置类
@Configuration @IntegrationComponentScan @Data public class MqttConfig { /** * mqtt地址 */ @Value("${mqtt.hostUrl}") private String hostUrl; /** * 用户名 */ @Value("${mqtt.username}") private String username; /** * 密码 */ @Value("${mqtt.password}") private String password; /** * 心跳间隔 */ @Value("${mqtt.keepAliveInterval}") private int keepAliveInterval; /** *连接超时 */ @Value("${mqtt.connectionTimeout}") private int connectionTimeout; /** *客户端id */ @Value("${mqtt.client-id}") private String clientId; /** *服务端id */ @Value("${mqtt.server-id}") private String serverId; /** *消息主题 */ @Value("${mqtt.data-topic}") private String dataTopic; /** *遗愿主题 */ @Value("${mqtt.will-topic}") private String willTopic; /** *遗愿消息内容 */ @Value("${mqtt.will-content}") private String willContent; /** *断开连接超时时间 */ @Value("${mqtt.completion-timeout}") private long completionTimeout; @Bean public MqttConnectOptions getMqttConnectOptions(){ MqttConnectOptions options = new MqttConnectOptions(); // 设置发布端地址,多个用逗号分隔, 如:tcp://111:1883,tcp://222:1883 // 当第一个111连接上后,222不会在连,如果111挂掉后,重试连111几次失败后,会自动去连接222 options.setServerURIs(hostUrl.split(",")); options.setKeepAliveInterval(keepAliveInterval); options.setUserName(username); options.setPassword(password.toCharArray()); options.setConnectionTimeout(connectionTimeout); // 设置“遗嘱”消息的话题,若客户端与服务器之间的连接意外中断,服务器将发布客户端的“遗嘱”消息。 options.setWill(willTopic,(clientId + willContent).getBytes(),1,true); // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录, // 把配置里的 cleanSession 设为false,客户端掉线后 服务器端不会清除session, // 当重连后可以接收之前订阅主题的消息。当客户端上线后会接受到它离线的这段时间的消息 options.setCleanSession(true); options.setMaxInflight(1000); //设置断开重新连接 options.setAutomaticReconnect(true); return options; } @Bean public MqttPahoClientFactory mqttPahoClientFactory(){ DefaultMqttPahoClientFactory clientFactory = new DefaultMqttPahoClientFactory(); clientFactory.setConnectionOptions(getMqttConnectOptions()); return clientFactory; } /** * 发送通道 */ @Bean public MessageChannel mqttOutBoundChannel(){ return new DirectChannel(); } /** * 发送消息配置 * @return */ @Bean @ServiceActivator(inputChannel = "mqttOutBoundChannel") public MessageHandler messageHandler(){ //clientId每个连接必须唯一,否则,两个相同的clientId相互挤掉线 //String clientIdStr = clientId + new SecureRandom().nextInt(10); MqttPahoMessageHandler mqttPahoMessageHandler = new MqttPahoMessageHandler(clientId,mqttPahoClientFactory()); //async如果为true,则调用方不会阻塞。而是在发送消息时等待传递确认。默认值为false(发送将阻塞,直到确认发送) mqttPahoMessageHandler.setAsync(true); mqttPahoMessageHandler.setDefaultTopic(dataTopic); mqttPahoMessageHandler.setDefaultQos(1); mqttPahoMessageHandler.setAsyncEvents(true); return mqttPahoMessageHandler; } /** * 接收通道 */ @Bean public MessageChannel mqttInboundChannel(){ return new DirectChannel(); } /** * 配置监听的 topic 支持通配符 * @return */ @Bean public MessageProducer inBound(){ String[] topics = new String[]{ "$SYS/brokers/+/clients/+/disconnected", //客户端下线主题 "$SYS/brokers/+/clients/+/connected", //客户端上线主题 // "$exclusive/", //排它策略前缀 dataTopic, willTopic }; //serverId每个连接必须唯一,否则,两个相同的serverId相互挤掉线 //String serverIdStr = serverId + new SecureRandom().nextInt(10); MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(serverId,mqttPahoClientFactory(),topics); adapter.setOutputChannel(mqttInboundChannel()); adapter.setDisconnectCompletionTimeout(completionTimeout); adapter.setConverter(new DefaultPahoMessageConverter()); adapter.setQos(1); return adapter; } /** * 通过通道获取数据 * @return */ @Bean @ServiceActivator(inputChannel = "mqttInboundChannel") public MessageHandler getInbound(){ MessageHandler messageHandler = new MessageHandler() { @Override public void handleMessage(Message<?> message) throws MessagingException { String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC).toString(); String payload = message.getPayload().toString(); //消息处理 //MyMessageHandler.msgHandler(topic,payload); System.out.println("消息主题:"+topic+",消息内容:"+payload); //处理订阅topic:(data/#)到的所有的数据 } }; return messageHandler; } /** * 连接失败会触发 * @param event */ @EventListener(classes = MqttConnectionFailedEvent.class) public void mqttConnectFailedEvent(MqttConnectionFailedEvent event){ System.out.println("mqttConnectionFailedEvent连接mqtt失败: "+event.toString()); } /** * @desc 当async和async事件(async-events)都为true时,将发出MqttMessageSentEvent * 它包含消息、主题、客户端库生成的消息id、clientId和clientInstance(每次连接客户端时递增) * @date 2021/7/22 *@param event * @return void */ @EventListener(classes = MqttMessageSentEvent.class) public void mqttMessageSentEvent(MqttMessageSentEvent event){ System.out.println("发送消息"+event.toString()); } /** * @desc 当async和async事件(async-events)都为true时,将发出MqttMessageDeliveredEvent * 当客户端库确认传递时,将发出MqttMessageDeliveredEvent。它包含messageId、clientId和clientInstance,使传递与发送相关。 * @date 2021/7/22 *@param event * @return void */ @EventListener(classes = MqttMessageDeliveredEvent.class) public void mqttMessageDeliveredEvent(MqttMessageDeliveredEvent event){ System.out.println("消息发送成功:"+event.toString()); } /** * @desc 成功订阅到主题,MqttSubscribedEvent事件就会被触发(多个主题,多次触发) * @date 2021/7/22 *@param event * @return void */ @EventListener(classes = MqttSubscribedEvent.class) public void mqttSubscribedEvent(MqttSubscribedEvent event){ System.out.println("消息订阅成功:"+event.toString()); } }
- 编写发送消息接口
@MessagingGateway(defaultRequestChannel = "mqttOutBoundChannel") public interface MqttGateway { /** * * @param data 消息 */ void send(String data); /** * * @param data 消息 * @param topic 主题 */ void send(String data, @Header(MqttHeaders.TOPIC) String topic); /** * * @param data 消息 * @param topic 主题 * @param qos 消息质量 */ void send(String data, @Header(MqttHeaders.TOPIC) String topic,@Header(MqttHeaders.QOS) int qos); }
- 编写 TestController
@RestController public class TestController { @Autowired private MqttGateway mqttGateway; @RequestMapping("/test") public String testMqtt(@RequestParam(value = "msg") String msg){ mqttGateway.send(msg,"/wvp_ptz",1); return "ok"; } }
- postman测试
idea控制台
mqtt面板
结束
到此springBoot已经集成mqtt了
本文来自博客园,作者:cxf0616,转载请注明原文链接:https://www.cnblogs.com/cxfbk/p/17191564.html
风起于青萍之末,浪成于微澜之间
每一份成功都源于每日的坚持
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结