MQTT同步通信实现

建议先阅读文末参考文章再回看本文实现

mqtt是发布订阅机制,消息发送方无法立即知道消息订阅方的返回消息。在一些场景下比如我通过mqtt给某温度传感器下发命令读取该设备的温度数据这时需要同步得到温度传感器返回的数据,这就需要把异步请求转化为同步请求。

下面参考https://www.cnblogs.com/goodAndyxublog/p/12393723.html所描述mq方案来实现。

1.方案整体流程

 1.发送mqtt消息生成DefaultFuture,等待返回消息。DefaultFuture的实现原理即为dubbo中DefaultFuture实现。DefaultFuture是本方案的核心


@RestController
@RequestMapping("mqtt")
public class TestController {
   @Autowired
   SynMqttSender synMqttSender;
    @PostMapping("send")
    public Message sendMsg(@RequestBody  Message message){
        DefaultFuture future = synMqttSender.sendMessage(message);
        return future.get();
    }
}

2 mqtt返回消息处理程序

  /**
     * MQTT消息处理器(消费者)
     */
    @Bean
    @ServiceActivator(inputChannel = CHANNEL_NAME_IN)
    public MessageHandler handler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                String topic = message.getHeaders().get("mqtt_receivedTopic").toString();

                if(topic.equals(Constant.MQTT_TOPIC_RES)){
                    String msg = message.getPayload().toString();
                    mqttResHandler.deal(JSONUtil.toBean(msg,com.ffy.mqtt.model.Message.class));
                }
                String msg = message.getPayload().toString();
                log.info("\n--------------------START-------------------\n" +
                        "接收到订阅消息:\ntopic:" + topic + "\nmessage:" + msg +
                        "\n---------------------END--------------------");
            }
        };
    }
@Component
public class MqttResHandler {


    public void deal(Message msg){
        //根据messageId判断是否是本机发送的消息
        Long msgId = msg.getMessageId();
        if(DefaultFuture.contains(msgId)){
            DefaultFuture.received(msg);
        }
    }
}

在参考文章中当接收到的异步返回的消息后通过mq广播给了所有机器进行处理,本场景中各服务订阅topic本身就能保证返回的消息被所有机器接收到。

实现要点在于DefeaultFuture的实现,参考文章已有详细说明。

2.最终效果演示

1.发送消息

2.为message生成一个唯一的messageId通过mqtt发送给订阅方。用mqtt.x模拟温度传感器订阅消息 

 3.返回响应消息带上接收到的messageId

 

 4 根据messageId找到唤醒等待的DefaultFuture返回数据

 本文采用rabbitmq作为mqtt-broker 

完整代码:https://github.com/setadd/mqtt

参考资料:

sprignboot集成mqtt

架构设计|异步请求如何同步处理?

Dubbo源码分析(十)同步调用与异步调用

源码分析Dubbo异步调用与事件回调机制

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值