springboot 集成 emqx 实现mqtt协议数据传输交互

3,265 阅读1分钟

安装下载emqx www.emqx.cn/downloads

image.png

第一步 引入mqtt

<dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
</dependency>       

第二步 配置

/**
MQTT协议--物联网
 */
@Configuration
@Slf4j
public class MqttConfig {
    private static final byte[] WILL_DATA;

    static {
        WILL_DATA = "offline".getBytes();

    }

    public static final String CHANNEL_NAME_IN = "mqttInboundChannel";
    public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";

    private static String username = "admin";
    private static String password = "admin";
    private static String url = "tcp://x.x.x.x:1883";
    private static String producerClientId = "pId" + IdUtil.createSnowflake(1, 1).nextIdStr();
//    private static String producerDefaultTopic = "/usr/plcnet/test/edge/d";
    private static String producerDefaultTopic = "BOX/4564651145456/sss";
    private static String consumerClientId = "cId" + IdUtil.createSnowflake(1,1).nextIdStr();
//    private static String consumerDefaultTopic = "/usr/plcnet/+/heart/u";
//    private static String consumerDefaultTopic = "BOX/#,/+/DevRecv/#";
        private static String consumerDefaultTopic = "/DevSend/#";
    @Bean
    public MqttConnectOptions getMqttConnectOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,
        // 这里设置为true表示每次连接到服务器都以新的身份连接
        options.setCleanSession(true);
        // 设置连接的用户名
        options.setUserName(username);
        // 设置连接的密码
        options.setPassword(password.toCharArray());
        options.setServerURIs(url.split(","));
        // 设置超时时间 单位为秒
        options.setConnectionTimeout(10);
        // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线,但这个方法并没有重连的机制
        options.setKeepAliveInterval(20);
        // 设置“遗嘱”消息的话题,若客户端与服务器之间的连接意外中断,服务器将发布客户端的“遗嘱”消息。
        options.setWill("willTopic", WILL_DATA, 2, false);
        return options;
    }

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(getMqttConnectOptions());
        return factory;
    }

    @Bean(name = CHANNEL_NAME_OUT)
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();

    }

    @Bean
    @ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(
                producerClientId,
                mqttClientFactory());
        messageHandler.setAsync(true);
        messageHandler.setDefaultTopic(producerDefaultTopic);
        return messageHandler;
    }

    @Bean
    public MessageProducer inbound() {
        // 可以同时消费(订阅)多个Topic
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(
                        consumerClientId, mqttClientFactory(),
                        consumerDefaultTopic.split(","));
        adapter.setCompletionTimeout(5000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(0);
        // 设置订阅通道
        adapter.setOutputChannel(mqttInboundChannel());
        return adapter;
    }

    @Bean(name = CHANNEL_NAME_IN)
    public MessageChannel mqttInboundChannel() {
        return new DirectChannel();

    }

    @Bean
    @ServiceActivator(inputChannel = CHANNEL_NAME_IN)
    public MessageHandler handler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                log.info("消息");
                log.info(message.getPayload().toString());
                log.info("头信息");
                log.info(JSON.toJSONString(message.getHeaders()));
                System.out.println(message.getPayload());
            }
        };

    }


}
@Component
@MessagingGateway(defaultRequestChannel = MqttConfig.CHANNEL_NAME_OUT)
public interface IMqttSender {

    void sendToMqtt(String data);

    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);

    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);


}