最近在做物联网项目,用到了Mqtt,后端框架使用了Springboot,因此采用Springboot整合Mqtt。
整合时参考了一下帖子:
https://blog.csdn.net/qq_40083897/article/details/106408822
单机测试可参考阿里物联网平台的demo:
https://www.alibabacloud.com/help/zh/doc-detail/146631.htm#task-2362406
其中在初始化订阅者时,已经预先设置了主题
@Bean
public MessageProducer mqttSubscriber() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter(mqttProperties.getClientId() + "_consumer", mqttPahoClientFactory(),
"topic1","topic2");
adapter.setCompletionTimeout(mqttProperties.getCompletionTimeout());
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(0);
adapter.setOutputChannel(mqttInboundChannel());
return adapter;
}
其中topic1和topic2在初始化后就可以订阅
但是在使用过程中想订阅新的主题怎么实现呢?
首先需要研究MessageProducer类有没有提供“添加主题”的方法,发现竟然没有!很意外。。。
但是发现返回的真正对象是MqttPahoMessageDrivenChannelAdapter的实例对象,因此可以断定MessageProducer是MqttPahoMessageDrivenChannelAdapter的引用类,即父类。
继续研究MqttPahoMessageDrivenChannelAdapter有没有“添加主题”的方法,突然发现,真的有
想法一:adapter有方法addTopic方法
在service或者controller中注入MessageProducer mqttSubscriber然后使用mqttSubscriber增加订阅的主题
竟然发现方法报错,反思:这个方法是子类独有,父类无法调用。
能不能强制转换为子类对象呢?强制转换方法没有报错
经过测试没有问题,可以使用,很棒!
想法二:直接实例化一个MqttPahoMessageDrivenChannelAdapter对象
@Bean
public MqttPahoMessageDrivenChannelAdapter mqttSubscriber() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter(mqttProperties.getClientId() + "_consumer", mqttPahoClientFactory(),
"topic1","topic2");
adapter.setCompletionTimeout(mqttProperties.getCompletionTimeout());
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(0);
adapter.setOutputChannel(mqttInboundChannel());
return adapter;
}
注入MqttPahoMessageDrivenChannelAdapter mqttSubscriber对象
经过测试也是可以实现的
很好的一次思考和解决问题的过程,希望对看到的朋友有帮助。
熟悉Spring IOC和@Bean注解的大神,应该都懂,献丑了。