我想使用SI中的Aggregator Endpoint聚合基于消息主题的MQTT消息,并在到目前为止收到所有部件(某些陀螺仪值:X,Y和Z)时释放聚合消息,到目前为止没有问题。 。 有用。 但是我想添加一个组超时,以便在一段时间内没有收到所有3个值时,消息将被丢弃,我可以等待新消息。
我的工作代码:
配置:
@SpringBootApplication
public class MqttListenerApplication {
public static void main(String[] args) {
SpringApplication.run(MqttListenerApplication.class, args);
}
@Bean
public MessageChannel mqttInputChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel filterOutputChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel aggregatorOutputChannel() {
return new DirectChannel();
}
@Bean
public MqttPahoClientFactory clientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName("demo:application");
options.setPassword("PwdApps".toCharArray());
factory.setConnectionOptions(options);
return factory;
}
@Bean
public MessageProducer inbound() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter("tcp://mqtt2.thingsplay.com:1883", "test-007", clientFactory(),"#");
adapter.setCompletionTimeout(5000);
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(1);
adapter.setOutputChannel(mqttInputChannel());
return adapter;
}
}
过滤器端点:
@MessageEndpoint
public class MqttFilter {
@Filter(
inputChannel = "mqttInputChannel",
outputChannel = "filterOutputChannel"
)
public boolean isValid(@Header("mqtt_receivedTopic") String topic, Message<?> message) {
if (topic.contains("testbw")) {
System.out.println("------ Valid Message ! ------");
return true;
} else {
return false;
}
}
}
聚合器端点:
@MessageEndpoint
public class GyroAggregator {
private static final Logger logger = LogManager.getLogger();
@Aggregator(
inputChannel = "filterOutputChannel",
outputChannel = "aggregatorOutputChannel"
)
public GyroCompleted aggregate(List<Message<?>> messages) {
GyroCompleted gyroCompleted = new GyroCompleted();
for (Message<?> message : messages) {
String topic = (String) message.getHeaders().get("mqtt_receivedTopic");
if (topic.contains("ACCX")) {
gyroCompleted.setAcc_x(Integer.valueOf((String) message.getPayload()));
} else if (topic.contains("ACCY")) {
gyroCompleted.setAcc_y(Integer.valueOf((String) message.getPayload()));
} else if (topic.contains("ACCZ")) {
gyroCompleted.setAcc_z(Integer.valueOf((String) message.getPayload()));
}
}
return gyroCompleted;
}
@ReleaseStrategy
public boolean hasAllAxes(List<Message<?>> messages) {
logger.debug("In Release Strategy method.");
logger.debug(messages);
boolean x = false, y = false, z = false;
for (Message<?> message : messages) {
String topic = (String) message.getHeaders().get("mqtt_receivedTopic");
if (topic.contains("ACCX")) {
x = true;
} else if (topic.contains("ACCY")) {
y = true;
} else if (topic.contains("ACCZ")) {
z = true;
}
}
logger.debug("Release Strategy method returning {}", x && y && z);
return x && y && z;
}
@CorrelationStrategy
public String correlateBy(@Header("mqtt_receivedTopic") String topic, Message<?> message) {
logger.debug("In Correlation Strategy method.");
String deviceId = topic.substring(0, topic.indexOf("/"));
logger.debug("Correlation Strategy returning Key : {}", deviceId);
return deviceId;
}
}
回声端点:
@MessageEndpoint
public class EchoServiceActivator {
private static final Logger logger = LogManager.getLogger();
@ServiceActivator(
inputChannel = "aggregatorOutputChannel"
)
public void echo(Message<?> message) {
logger.debug("Echo : " + message);
}
}
但是对于组超时点,我无法使其工作...尽管文档中说了这样,但注释中没有配置:
xml元素提供的所有配置选项也都是 可用于@Aggregator注释。
但是下面几行是这样说的:
聚合器的注释配置(@Aggregator等) 组件仅涵盖简单的用例,其中大多数默认选项是 足够。如果您需要使用以下选项来更好地控制这些选项 注释配置,请考虑将@Bean定义用于 AggregatingMessageHandler并将其@Bean方法标记为 @ServiceActivator
问题是我无法使@Bean工作...
我试图将其放在带有@MessageEndpoint注释的类中,但它也不起作用。我以为它将为聚集器自动装配所有组件。
我如何使其工作?
答案 0 :(得分:1)
使用Java DSL更容易。像这样:
@Bean
public IntegrationFlow aggregatorFlow(GyroAggregator agg) {
return IntegrationFlows.from("filterOutputChannel")
.aggregate(a -> a
.processor(agg)
.groupTimeout(500L))
.channel("aggregatorOutputChannel")
.get();
}
当然,您可以将MQTT适配器和过滤器连接到同一流程中。
如果要将处理程序定义为@Bean
,请在ctor中使用new SimpleMessageStore()
。