使用相同的连接发布和订阅带有Spring Integration Java DSL的mqtt主题
我有以下配置:使用相同的连接发布和订阅带有Spring Integration Java DSL的mqtt主题,java,spring,integration,mqtt,dsl,Java,Spring,Integration,Mqtt,Dsl,我有以下配置: @Configuration public class MqttConfig { @Autowired private MqttClientProperties mqttClientProperties; @Autowired ActionHandlerManager actionHandlerManager; @Autowired private ActionDispatchManager actionDispatchMan
@Configuration
public class MqttConfig {
@Autowired
private MqttClientProperties mqttClientProperties;
@Autowired
ActionHandlerManager actionHandlerManager;
@Autowired
private ActionDispatchManager actionDispatchManager;
@Autowired
@Qualifier("messagePackObjectMapper")
private ObjectMapper messagePackObjectMapper;
@Bean
public IntegrationFlow getMqttInFlow() {
return IntegrationFlows.from(getMqttInBound())
.handle(actionDispatchManager)
.get();
}
@Bean
public MessageProducerSupport getMqttInBound() {
String[] allTopics = getActionHandlers().parallelStream()
.flatMap(actionHandler -> actionHandler.getTopics().stream())
.map(topic -> topic.replaceAll("\\{(.*?)\\}", "+"))
.toArray(String[]::new);
int[] allQos = getActionHandlers().parallelStream()
.flatMap(actionHandler -> actionHandler.getQos().stream())
.mapToInt(Integer::intValue)
.toArray();
MqttPahoMessageDrivenChannelAdapter messageDrivenChannelAdapter = new MqttPahoMessageDrivenChannelAdapter("exhibitManager",
getMqttClientFactory(), allTopics);
messageDrivenChannelAdapter.setCompletionTimeout(5000);
messageDrivenChannelAdapter.setConverter(getMessageConverter());
messageDrivenChannelAdapter.setQos(allQos);
return messageDrivenChannelAdapter;
}
@Bean
@ServiceActivator(inputChannel = "mqttOutBoundChannel")
public MessageHandler getMqttOutBound() {
MqttPahoMessageHandler mqttMessageHandler = new MqttPahoMessageHandler("exhibitManager", getMqttClientFactory());
mqttMessageHandler.setAsync(true);
mqttMessageHandler.setDefaultTopic("/test");
return mqttMessageHandler;
}
@MessagingGateway(defaultRequestChannel = "mqttOutBoundChannel")
public interface MqttGateway {
void sendMessage(byte[] message);
}
@Bean
public MqttPahoClientFactory getMqttClientFactory() {
DefaultMqttPahoClientFactory mqttClientFactory = new DefaultMqttPahoClientFactory();
mqttClientFactory.setServerURIs(String.format("tcp://%s:%s", mqttClientProperties.getHost(), mqttClientProperties.getPort()));
mqttClientFactory.setWill(new DefaultMqttPahoClientFactory.Will("disconnect", "test".getBytes(), 0, false));
mqttClientFactory.setCleanSession(false);
return mqttClientFactory;
}
@Bean
public MqttMessageConverter getMessageConverter() {
DefaultPahoMessageConverter messageConverter = new DefaultPahoMessageConverter();
messageConverter.setPayloadAsBytes(true);
return messageConverter;
}
@Bean
public List<ActionHandler> getActionHandlers() {
return actionHandlerManager.getActionHandlers()
.collect(Collectors.toList());
}
}
@配置
公共类MqttConfig{
@自动连线
专用MqttClientProperties MqttClientProperties;
@自动连线
ActionHandlerManager ActionHandlerManager;
@自动连线
私人ActionDispatchManager ActionDispatchManager;
@自动连线
@限定符(“messagePackObjectMapper”)
私有对象映射器messagePackObjectMapper;
@豆子
公共集成流getMqttInFlow(){
返回IntegrationFlows.from(getMqttInBound())
.handle(actionDispatchManager)
.get();
}
@豆子
public MessageProducerSupport getMqttInBound(){
String[]allTopics=getActionHandlers().parallelStream()
.flatMap(actionHandler->actionHandler.getTopics().stream())
.map(主题->主题.replaceAll(“\\{(.*?\\})”,“+”)
.toArray(字符串[]::新建);
int[]allQos=getActionHandlers().parallelStream()
.flatMap(actionHandler->actionHandler.getQos().stream())
.mapToInt(整数::intValue)
.toArray();
MQTTPAHomeMessageDrivenChannelAdapter messageDrivenChannelAdapter=新MQTTPAHomeMessageDrivenChannelAdapter(“参展商经理”,
getMqttClientFactory(),所有主题);
messageDrivenChannelAdapter.setCompletionTimeout(5000);
setConverter(getMessageConverter());
messageDrivenChannelAdapter.setQos(allQos);
返回消息drivenchanneladapter;
}
@豆子
@ServiceActivator(inputChannel=“mqttOutBoundChannel”)
public MessageHandler getMqttOutBound(){
MQTTPAHomeMessageHandler mqttMessageHandler=新MQTTPAHomeMessageHandler(“exhibitManager”,getMqttClientFactory());
mqttMessageHandler.setAsync(true);
mqttMessageHandler.setDefaultTopic(“/test”);
返回mqttMessageHandler;
}
@MessagingGateway(defaultRequestChannel=“mqttOutBoundChannel”)
公共接口MqttGateway{
无效发送消息(字节[]消息);
}
@豆子
公共MqttPahoClientFactory getMqttClientFactory(){
DefaultMqttPahoClientFactory mqttClientFactory=新的DefaultMqttPahoClientFactory();
mqttClientFactory.SetServerURI(String.format(“tcp://%s:%s”、mqttClientProperties.getHost()、mqttClientProperties.getPort());
setWill(新的DefaultMqttPahoClientFactory.Will(“disconnect”,“test”.getBytes(),0,false));
mqttClientFactory.setCleanSession(false);
返回mqttClientFactory;
}
@豆子
公共MqttMessageConverter getMessageConverter(){
DefaultPaHomeMessageConverter messageConverter=新的DefaultPaHomeMessageConverter();
messageConverter.setPayloadAsBytes(true);
返回消息转换器;
}
@豆子
公共列表getActionHandlers(){
返回actionHandlerManager.getActionHandlers()
.collect(Collectors.toList());
}
}
使用此配置,客户端会多次断开和重新连接。作为具有相同clientId的发布者和订阅者连接到主题的最佳配置是什么?这是否仅在应用程序启动前几分钟发生?如果是这样的话,我可能会为您提供一个解决方案。在发布主题消息时,客户端会断开连接。我认为另一个连接是使用相同的客户端ID创建的。使用相同的客户端ID多次尝试连接可以解释您的问题。您是否已将代码更改为共享单个mqtt连接?您似乎至少有两次对getMqttClientFactory的调用,每次调用它时都会创建一个新的DefaultMqttPahoClientFactory—这似乎不对。感谢您的帮助reply@blacksword使用Spring时的另一个建议是使用注入法,而不是ivoking法。例如@Bean public IntegrationFlow getMqttInFlow(MessageProducerSupport mqttInbound){返回IntegrationFlows.from(mqttInbound).handle(actionDispatchManager.get();}