使用相同的连接发布和订阅带有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();}