J'utilise l'intégration Spring et son support pour MQTT; J'ai vu la documentation sur l'intégration de Spring et mon scénario de test simple consiste à publier un message sur un sujet MQTT. La documentation Spring se trouve ici: http://docs.spring.io/spring-integration/reference/html/mqtt.html#_configuring_with_Java_configuration_15
J'utilise ces versions:
J'ai construit cette classe de configuration simple:
@Configuration
@IntegrationComponentScan
public class CommunicationServerApplication
{
@Bean
public MqttPahoClientFactory mqttClientFactory()
{
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setServerURIs(mqttServerUris);
if (StringUtils.hasText(mqttUsername) && StringUtils.hasText(mqttPassword))
{
factory.setUserName(mqttUsername);
factory.setPassword(mqttPassword);
}
factory.setConnectionTimeout(mqttConnectionTimeout);
factory.setKeepAliveInterval(mqttKeepAliveInterval);
factory.setPersistence(new MqttDefaultFilePersistence(mqttPersistenceFileDirectory));
return factory;
}
@Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel", autoStartup="true")
public MessageHandler mqttOutbound()
{
String clientId = mqttClientId;
if( !StringUtils.hasText(clientId) )
{
clientId = UUID.randomUUID().toString();
}
MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId, mqttClientFactory());
messageHandler.setAsync(true);
messageHandler.setDefaultTopic(mqttTopic);
if( mqttQos >= 0 && mqttQos <=2 )
{
messageHandler.setDefaultQos(mqttQos);
}
return messageHandler;
}
@Bean
public MessageChannel mqttOutboundChannel()
{
DirectChannel dc = new DirectChannel();
return dc;
}
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface MqttMsgproducer
{
void sendToMqtt(String data);
}
}
Et puis j'ai utilisé ce cas de test simple:
@ContextConfiguration(value ={ "classpath:app-ctx.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class SimpleMqttTestSuite
{
private static final Logger logger = LoggerFactory.getLogger(SimpleMqttTestSuite.class.getName());
@Autowired
private MqttMsgproducer sender;
@Test
public void startServerTest()
{
try
{
sender.sendToMqtt("Hello");
}
catch (Exception e)
{
logger.error("Error", e);
}
}
}
Mon app-ctx.xml est:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="it.olegna.test.integration" />
<context:property-placeholder location="classpath:configuration.properties"
order="0" ignore-resource-not-found="true" ignore-unresolvable="true" />
</beans>
En exécutant le test simple, je rencontre cette erreur:
2016-12-20 10:46:33,889 49967 [nioEventLoopGroup-3-1] ERROR - Errore
org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'org.springframework.context.support.GenericApplicationContext@2e6a8155.mqttOutboundChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.Java:81) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.Java:423) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.Java:373) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.Java:115) ~[spring-messaging-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.Java:45) ~[spring-messaging-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.Java:105) ~[spring-messaging-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.Java:143) ~[spring-messaging-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.Java:135) ~[spring-messaging-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.Java:375) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.Java:477) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.Java:429) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.Java:420) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.integration.gateway.GatewayCompletableFutureProxyFactoryBean.invoke(GatewayCompletableFutureProxyFactoryBean.Java:65) ~[spring-integration-core-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:179) ~[spring-aop-4.3.4.RELEASE.jar:4.3.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.Java:213) ~[spring-aop-4.3.4.RELEASE.jar:4.3.4.RELEASE]
Je ne peux pas comprendre ce qui me manque dans la configuration. Quelqu'un peut-il me donner un pourboire?
merci
Angelo
Votre solution est incorrecte - vous ne devez pas vous abonner dans une définition de bean channel. Je crois que votre problème est que vous manquez @EnableIntegration
sur la classe.
J'ai résolu mon problème
C'était lié au fait que j'ai construit la Manche mais maintenant le gestionnaire a été abonné
Dans ma classe d'application, j'ai fait ce qui suit:
@Bean
public MessageChannel mqttOutboundChannel()
{
DirectChannel dc = new DirectChannel();
dc.subscribe(mqttOutbound());
return dc;
}
Comme vous pouvez le voir maintenant, j'ajoute manuellement abonnez le bean mqttOutbound (le gestionnaire de messages) au canal
En faisant de cette façon tout fonctionne
J'espère que cela peut aider
Angelo
MISE À JOUR APRÈS RÉPONSE DE Gary Russell
Comme suggéré par Gary Russell, je ne suis pas abonné à la chaîne
J'ai ajouté l'annotation @EnableIntegration
Donc, ma classe d'application est maintenant la suivante:
@Configuration
@IntegrationComponentScan
@EnableIntegration
public class CommunicationServerApplication
{
@Bean
public MqttPahoClientFactory mqttClientFactory()
{
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setServerURIs(mqttServerUris);
if (StringUtils.hasText(mqttUsername) && StringUtils.hasText(mqttPassword))
{
factory.setUserName(mqttUsername);
factory.setPassword(mqttPassword);
}
factory.setConnectionTimeout(mqttConnectionTimeout);
factory.setKeepAliveInterval(mqttKeepAliveInterval);
factory.setPersistence(new MqttDefaultFilePersistence(mqttPersistenceFileDirectory));
return factory;
}
@Bean
@ServiceActivator(inputChannel = "mqttOutboundChannel", autoStartup="true")
public MessageHandler mqttOutbound()
{
String clientId = mqttClientId;
if( !StringUtils.hasText(clientId) )
{
clientId = UUID.randomUUID().toString();
}
MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId, mqttClientFactory());
messageHandler.setAsync(true);
messageHandler.setDefaultTopic(mqttTopic);
if( mqttQos >= 0 && mqttQos <=2 )
{
messageHandler.setDefaultQos(mqttQos);
}
return messageHandler;
}
@Bean
public MessageChannel mqttOutboundChannel()
{
DirectChannel dc = new DirectChannel();
return dc;
}
@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface MqttMsgproducer
{
void sendToMqtt(String data);
}
}