Spring整合MQTT

Spring整合提供inbound与outbound通道适配器以支持MQTT协议,当前实现使用Eclipse Paho MQTT Client库。
通过DefaultMqttPahoClientFactory配置两个适配器,参考Paho文档获取关于配置选项更多的信息。

Inbound(消息驱动)通道适配器

     由MqttPahoMessageDrivenChannelAdapter实现,为方便起见,可以采用命名空间的方式进行配置。最小配置可能会是这样:
<bean id="clientFactory"
  class="org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory">
 <property name="userName" value="${mqtt.username}"/>
 <property name="password" value="${mqtt.password}"/>
</bean>

<int-mqtt:message-driven-channel-adapter id="mqttInbound"
 client-id="${mqtt.default.client.id}.src"
 url="${mqtt.url}"
 topics="sometopic"
 client-factory="clientFactory"
 channel="output"/>
属性:
<int-mqtt:message-driven-channel-adapter id="oneTopicAdapter"
 client-id="foo"
 url="tcp://localhost:1883" 
 topics="bar,baz"
 qos="1,2"
 converter="myConverter"
 client-factory="clientFactory"
 send-timeout="123"
 error-channel="errors"
 recovery-interval="10000"
 channel="out" />
1)客户端id
2)代理URL
3)适配器会接受到消息的一组以逗号分隔的主题
4)以逗号分隔的一组QoS值,可以是所有主题运用单一值,或者每一个主题一个值(列表必须同样长度)
5)MqttMessageConverter(可选项),默认DefaultPahoMessageConverter生成消息带字符串载荷(默认),携带头部包括:
     mqtt_topic     接收消息主题
     mqtt_duplicate     如果消息重复,值为true
     mqtt_qos     业务质量
  DefaultPahoMessageConverter可配置为返回载荷原始byte[]类型,通过将其声明为一个实体类<bean/>,并且设定payloadAsBytes属性
6)客户端工厂
7)发送超时-如果通道可能会阻塞,才会运用(例如当前已满的边界QueueChannel)
8)错误通道--如果使用的话,ErrorMessage消息下行异常会发送至该通道,载荷为MessagingException,包含错误消息与原因
9)恢复间隔--控制在故障之后适配器会尝试重新连接的时间间隔,默认为10000ms(10s)
     从4.1版本开始,编程方式改变适配器订阅的主题可以省略url,DefaultMqttPahoClientFactory属性serverURIs可以提供服务端URI,例如,这将使能连接至HA高可用簇。
     从4.2.2版本开始,当适配器成功订阅至主题后,发布MqttSubscribedEvent,当连接/订阅失败时,发布MqttConnectionFailedEvent。这些事件可以由实现ApplicationListener接口的实体类获取。
      新的属性recoveryInterval控制在故障之后适配器会尝试重新连接的时间间隔,默认为10000ms(10s)
     在4.2.3版本之前,当适配器停止后,客户端总是会解除订阅。这是不正确的,因为如果客户端QoS大于0,我们需要保持订阅以便适配器停止时到达的消息在下一次开始时会传送。这也需要设置客户端工厂cleanSession属性为false,默认值为true。
     从4.2.3版本开始,适配器不会解除订阅(默认),如果cleanSession值为false。可以重写该行为,通过设置工厂属性consumerCloseAction,可以有以下值:UNSUBSCRIBE_ALWAYS, UNSUBSCRIBE_NEVER以及UNSUBSCRIBE_CLEAN,后者(默认)会解除订阅仅当cleanSession属性值为true。
     回退至4.2.3之前的行为,使用UNSUBSCRIBE_ALWAYS。

运行时增加/删除主题
     从4.1版本开始,是可能的。提供方法addTopic()与removeTopic(),当增加主题时,可以可选地指明QoS(默认值为1),也可以通过发送合适的消息至<control-bus/>,携带合适的载荷修改主题:
myMqttAdapter.addTopic('foo', 1)
     停止/启动适配器对主题列表无影响(不会回退至配置里原始设定值),更改不会保留至超出应用上下文生命周期;新的应用上下文会回退到配置的设定值。
     当适配器停止时(或者从代理断开连接时)改变主题会在下一次连接建立时生效。

Java配置
     下面的Spring Boot应用程序提供了一个运用Java配置来配置inbound适配器的例子:
@SpringBootApplication
public class MqttJavaApplication {
    public static void main(String[] args) {
    	new SpringApplicationBuilder(MqttJavaApplication.class)
    			.web(false)
    			.run(args);
    }

    @Bean
    public MessageChannel mqttInputChannel() {
    	return new DirectChannel();
    }

    @Bean
    public MessageProducer inbound() {
    	MqttPahoMessageDrivenChannelAdapter adapter =
    			new MqttPahoMessageDrivenChannelAdapter("tcp://localhost:1883", "testClient",
    			                                 "topic1", "topic2");
    	adapter.setCompletionTimeout(5000);
    	adapter.setConverter(new DefaultPahoMessageConverter());
    	adapter.setQos(1);
    	adapter.setOutputChannel(mqttInputChannel());
    	return adapter;
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public MessageHandler handler() {
    	return new MessageHandler() {
    		@Override
    		public void handleMessage(Message<?> message) throws MessagingException {
    			System.out.println(message.getPayload());
    		}

    	};
    }

}

Outbound通道适配器

     由ConsumerEndpoint内包装的MqttPahoMessageHandler实现,为方便起见,可以采用命名空间的方式配置:
     从版本4.1开始,适配器支持异步发送,避免阻塞直到传送确认,如果想要的话,应用事件可被发出使能应用确认传递。
属性:
<int-mqtt:outbound-channel-adapter id="withConverter"
	client-id="foo"  
	url="tcp://localhost:1883"  
	converter="myConverter"  
	client-factory="clientFactory"  
	default-qos="1"  
	default-retained="true"  
	default-topic="bar"  
	async="false"  
	async-events="false"  
	channel="target" />
1)客户端id
2) 代理URL
3)MqttMessageConverter(可选),默认DefaultPahoMessageConverter识别以下头部:
     mqtt_topic     消息发送主题
     mqtt_retained     如果消息保留的话,值为true
     mqtt_qos     业务质量
4)客户端工厂
5)默认业务质量(用于未发现mqtt_qos头部的情况),如果自定义converter提供的话,不允许采用
6)保留标记符默认值(用于未发现mqtt_retained头部的情况),如果自定义converter提供的话,不允许采用
7)消息发送默认主题(用于未发现mqtt_topic头部的情况)
8)当为true,当发送消息时,调用者不会阻塞等待传送确认,默认值:false(发送阻塞直到传送确认)
9)当async和async-events都为true时,发出MqttMessageSentEvent事件,包含消息、主题以及由客户端库生成的消息id,客户端id和客户端实例(每次客户端连接增加)。当传送由客户端库确认,发出MqttMessageDeliveredEvent,包含消息号、客户端号和客户端实例,使传送与发送相关联。这些事件可以由任意ApplicationListener接收,或者通过事件inbound通道适配器。注意:在MqttMessageSentEvent之前可能会接收到MqttMessageDeliveredEvent。默认值为false。

     从版本4.1开始,可以省略url,DefaultMqttPahoClientFactory属性serverURIs可以提供服务器URI。例如,这将使能连接至HA高可用簇。
Java
     下面的Spring Boot应用程序给出了一个使用Java配置配置outbound适配器的例子:
@SpringBootApplication
@IntegrationComponentScan
public class MqttJavaApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context =
        		new SpringApplicationBuilder(MqttJavaApplication.class)
        				.web(false)
        				.run(args);
        MyGateway gateway = context.getBean(MyGateway.class);
        gateway.sendToMqtt("foo");
    }

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setServerURIs("tcp://host1:1883", "tcp://host2:1883");
        factory.setUserName("username");
        factory.setPassword("password");
        return factory;
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel")
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler =
                       new MqttPahoMessageHandler("testClient", mqttClientFactory());
        messageHandler.setAsync(true);
        messageHandler.setDefaultTopic("testTopic");
        return messageHandler;
    }

    @Bean
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }

    @MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
    public interface MyGateway {
        void sendToMqtt(String data);
    }
}
  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
要在Spring中集成MQTT进行物联网通信,可以使用Eclipse Paho MQTT客户端库。以下是集成步骤: 1. 添加Paho依赖 在pom.xml中添加以下依赖: ``` <dependency> <groupId>org.eclipse.paho</groupId> <artifactId>org.eclipse.paho.client.mqttv3</artifactId> <version>1.2.0</version> </dependency> ``` 2. 创建MQTT配置类 创建一个类来配置MQTT连接的参数,例如主机名、端口号、用户名、密码等。 ``` @Configuration public class MqttConfig { @Value("${mqtt.brokerUrl}") private String brokerUrl; @Value("${mqtt.clientId}") private String clientId; @Value("${mqtt.username}") private String username; @Value("${mqtt.password}") private String password; @Bean public MqttConnectOptions mqttConnectOptions() { MqttConnectOptions options = new MqttConnectOptions(); options.setCleanSession(true); options.setUserName(username); options.setPassword(password.toCharArray()); return options; } @Bean public MqttClient mqttClient() throws MqttException { return new MqttClient(brokerUrl, clientId); } } ``` 3. 创建MQTT服务类 创建一个类来发送和接收MQTT消息。在该类中,可以注入MqttClient和MqttConnectOptions。 ``` @Service public class MqttService { @Autowired private MqttClient mqttClient; @Autowired private MqttConnectOptions mqttConnectOptions; public void sendMessage(String topic, String message) throws MqttException { MqttMessage mqttMessage = new MqttMessage(message.getBytes()); mqttClient.connect(mqttConnectOptions); mqttClient.publish(topic, mqttMessage); mqttClient.disconnect(); } public void subscribe(String topic, MqttCallback callback) throws MqttException { mqttClient.connect(mqttConnectOptions); mqttClient.setCallback(callback); mqttClient.subscribe(topic); } } ``` 4. 发送MQTT消息 在需要发送MQTT消息的地方,注入MqttService并调用sendMessage方法。 ``` @Autowired private MqttService mqttService; public void sendMqttMessage(String topic, String message) throws MqttException { mqttService.sendMessage(topic, message); } ``` 5. 接收MQTT消息 实现MqttCallback接口,并在subscribe方法中将其传递给MqttClient。当收到MQTT消息时,会回调messageArrived方法。 ``` @Component public class MyMqttCallback implements MqttCallback { @Override public void connectionLost(Throwable throwable) { // 连接丢失 } @Override public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception { // 收到消息 } @Override public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) { // 消息发送完成 } } @Autowired private MqttService mqttService; @Autowired private MyMqttCallback myMqttCallback; public void subscribeMqttMessage(String topic) throws MqttException { mqttService.subscribe(topic, myMqttCallback); } ``` 以上是在Spring中集成MQTT进行物联网通信的基本步骤。需要注意的是,MQTT是基于TCP协议的,因此需要确保网络通畅。另外,MQTT的QoS级别有三个,分别是0、1和2,不同的级别会影响消息的可靠性和传输效率,需要根据实际情况进行选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值