mqtt发布和订阅消息

mqtt发布和订阅消息

mqtt连接信息配置:

mqtt_username=×××××
#MQTT-密码,需要解密
mqtt_password=×××××
mqtt_url=tcp://ip:1883
#MQTT-订阅的主题
mqtt_default_topic=×××××××
#两个客户端的clientId不能相同,生产者和消费者的clientId不能相同
mqtt_client_id=×××××
mqtt_completionTimeout=1000

创建连接,生产者和消费者配置

import com.hikvision.yqclgk.util.BlockThreadPool;
import com.hikvision.yqclgk.util.MyRunable;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;


/**
 *〈MQTT接收消息处理〉
 * **/
@Slf4j
@Configuration
@IntegrationComponentScan
public class MqttReceiveClient {

    @Autowired
    BlockThreadPool blockThreadPool;

    @Value("${mqtt_username}")
    private String username;

    @Value("${mqtt_password}")
    private String password;

    @Value("${mqtt_url}")
    private String hostUrl;

    @Value("${mqtt_client_id}")
    private String clientId;

    //订阅主题(#订阅主题,多个用‘,’隔开,如:topic,YIHON_WQ_M)
    @Value("${mqtt_default_topic}")
    private String defaultTopic;

    @Value("${mqtt_completionTimeout}")
    private int completionTimeout;   //连接超时


    @Bean(value = "getMqttConnectOptions")
    public MqttConnectOptions getMqttConnectOptions() {
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setUserName(username);
        mqttConnectOptions.setPassword(password.toCharArray());
        mqttConnectOptions.setServerURIs(new String[]{hostUrl});
        //cleanSession 设为 true;当客户端掉线时;服务器端会清除 客户端session;重连后 客户端会有一个新的session,cleanSession
        // 设为false,客户端掉线后 服务器端不会清除session,当重连后可以接收之前订阅主题的消息。当客户端上线后会接受到它离线的这段时间的消息
        mqttConnectOptions.setCleanSession(false);
        // 设置会话心跳时间 单位为秒
        mqttConnectOptions.setKeepAliveInterval(2);
        return mqttConnectOptions;
    }

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

    //接收通道
    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    //配置client,监听的topic
    @Bean
    public MessageProducer inbound() {
        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(clientId + "_inbound2", mqttClientFactory(), defaultTopic.trim().split(","));
        adapter.setCompletionTimeout(completionTimeout);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(2);
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }

    //通过通道获取数据
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public MessageHandler handler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                log.info("主题:{},QOS:{},消息接收到的数据:{}", message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC), message.getHeaders().get(MqttHeaders.RECEIVED_QOS), message.getPayload());
            }
        };
    }


   //生产者
    @Bean
    @ServiceActivator(inputChannel = "mqttOutboundChannel")
    public MessageHandler mqttOutbound() {
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId, mqttClientFactory());
        messageHandler.setDefaultTopic(defaultTopic);
        //如果设置成true,即异步,发送消息时将不会阻塞。
        messageHandler.setAsync(true);
        //设置默认QoS
        messageHandler.setDefaultQos(0);
        DefaultPahoMessageConverter defaultPahoMessageConverter = new DefaultPahoMessageConverter();
        //发送默认按字节类型发送消息
//        defaultPahoMessageConverter.setPayloadAsBytes(true);
        messageHandler.setConverter(defaultPahoMessageConverter);
        return messageHandler;
    }

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

import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.handler.annotation.Header;

@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
public interface TestGateway {

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


    // 定义重载方法,用于消息发送
    void sendToMqtt(String payload);
    // 指定topic进行消息发送
    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, byte[] payload);

}

往mqtt发送消息测试:

   @Autowired
    private TestGateway mqttGateway;

    @GetMapping("/testMqtt")
    public String sendMqtt(@RequestParam(value = "topic") String topic, @RequestParam(value = "message") String message) {
        mqttGateway.sendToMqtt(topic, message);
        return "SUCCESS";
    }

用postman调用该方法,即可。
在这里插入图片描述

MQTT是一种轻量级的发布/订阅协议,让我们来看看如何使用C语言实现MQTT发布订阅接口。 首先,需要使用MQTT客户端库,例如Eclipse Paho,这是一款流行的跨平台MQTT客户端库,支持C语言。可以通过以下代码行安装Eclipse Paho: ``` git clone https://github.com/eclipse/paho.mqtt.c.git cd paho.mqtt.c make ``` 接下来,让我们看看如何实现MQTT发布订阅接口: ### MQTT发布接口 ``` #include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientPub" #define TOPIC "MQTT Examples" #define PAYLOAD "Hello World!" #define QOS 1 #define TIMEOUT 10000L int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } pubmsg.payload = PAYLOAD; pubmsg.payloadlen = strlen(PAYLOAD); pubmsg.qos = QOS; pubmsg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); printf("Message with delivery token %d delivered\n", token); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 这段代码使用Eclipse Paho库实现了MQTT发布接口。首先,通过MQTTClient_create函数创建MQTT客户端,然后使用MQTTClient_connect函数连接到MQTT代理。接下来,设置MQTT消息的主题、负载、QoS和保留。最后,使用MQTTClient_publishMessage函数将消息发布MQTT代理,使用MQTTClient_waitForCompletion函数等待发布完成,并使用MQTTClient_disconnect函数断开连接。 ### MQTT订阅接口 ``` #include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientSub" #define TOPIC "MQTT Examples" #define QOS 1 #define TIMEOUT 10000L volatile MQTTClient_deliveryToken deliveredtoken; void delivered(void *context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { printf("Message arrived\n"); printf(" topic: %s\n", topicName); printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } void connlost(void *context, char *cause) { printf("\nConnection lost\n"); printf(" cause: %s\n", cause); } int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_token token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } MQTTClient_subscribe(client, TOPIC, QOS); MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered); while (1) { // do something } MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 这段代码使用Eclipse Paho库实现了MQTT订阅接口。首先,通过MQTTClient_create函数创建MQTT客户端,然后使用MQTTClient_connect函数连接到MQTT代理。接下来,使用MQTTClient_subscribe函数订阅MQTT消息,并设置MQTTClient_setCallbacks回调函数处理MQTT消息。最后,使用while循环等待MQTT消息的到来。 以上就是使用C语言实现MQTT发布订阅接口的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值