appollo消息服务器,Springboot 集成 MQTT —— web 服务端实现(apollo 客户端)-Go语言中文社区...

基于 MQTT 可以实现很多场景,例如现在使用比较多的物联网,还有消息的实时推送。联网的设备连接上 apollo 服务器以后,一直监听 apollo 推送过来的信令/消息即可。

a10259585498945e760f41e33047c28d.png

1、web 服务端向联网的设备推送信令/消息,上述截图的流程(1.1-1.2)。

1.1、web 服务端向 apollo 服务器发送信令/消息。

1.2、联网的设备通过订阅的主题,收到 web 服务端推送的信令/消息。

2、联网的设备 1 向联网的设备 2 发送信令/消息,上述截图的流程(2.1-2.4)。

2.1、设备 1 向 apollo 服务器发送接收方为设备 2 的消息/信令。

2.2、设备 2 向 web 服务端发起登录。

2.3、设备 2 在 web 服务端登录成功后,设备 2 与 apollo 服务器建立长连接。

2.4、设备 2 通过订阅的主题,收到设备 1 推送的信令/消息。

现在,整体结构已经比较明显了,接下来就会介绍 web 服务端的实现

基于 MQTT 长连接的 web 端实现

基于《Springboot 集成 MQTT —— 搭建 apollo 服务器(Windows)》 一文中搭建的 apollo 服务器,web 端需要配置 apollo 的连接。

9bec1eeb523f7a40f5c081143a9750ff.png

标记部分的内容如下

# 用户名

mqtt.username=admin

# 密码

mqtt.password=password

mqtt.url=tcp://127.0.0.1:61613

# 生产者客户端 ID

mqtt.send.clientId=mqttSendClient

# 消费者客户端 ID

mqtt.recv.clientId=mqttRecvClient

添加上述配置的时候,应该会发现,有些内容不会自动提示,我们需要手动的将上述配置信息配置到 MQTT 客户端的实例中。新增 MqttConfig 类。

import org.eclipse.paho.client.mqttv3.MqttConnectOptions;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

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;

@Configuration

public class MqttConfig {

private static final Logger LOGGER = LoggerFactory.getLogger(MqttConfig.class);

public static final String CHANNEL_RECV = "recvMsgChannel"; // 订阅消息的信道

public static final String CHANNEL_SEND = "sendMsgChannel"; // 发布消息的信道

public static final String TOPIC = "topic";

@Value("${mqtt.username}")

private String username;

@Value("${mqtt.password}")

private String password;

@Value("${mqtt.url}")

private String url;

@Value("${mqtt.send.clientId}")

private String senderClientId;

@Value("${mqtt.recv.clientId}")

private String recverClientId;

// MQTT 客户端的连接器哦诶之

@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(",")); // 连接的服务器 url

options.setConnectionTimeout(10); // 超时时间(单位:s)

options.setKeepAliveInterval(20); // 保活心跳(单位:s),此方法没有重连机制

return options;

}

// 构造 MQTT 客户端

@Bean

public MqttPahoClientFactory mqttClientFactory() {

DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();

factory.setConnectionOptions(getMqttConnectOptions());

return factory;

}

// MQTT 生产者客户端

@Bean

@ServiceActivator(inputChannel = CHANNEL_SEND)

public MessageHandler mqttMsgSend() {

MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(senderClientId, mqttClientFactory());

messageHandler.setAsync(true);

return messageHandler;

}

// MQTT 消息订阅绑定(消费者)

@Bean

public MessageProducer mqttMsgRecv() {

// 可以订阅多个 Topic 的消息

MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(

recverClientId, mqttClientFactory(), TOPIC.split(","));

adapter.setCompletionTimeout(5000);

adapter.setConverter(new DefaultPahoMessageConverter());

adapter.setQos(2);

adapter.setOutputChannel(mqttInboundChannel()); // 设置订阅通道

return adapter;

}

// MQTT信息通道(消费者)

@Bean(name = CHANNEL_RECV)

public MessageChannel mqttInboundChannel() {

return new DirectChannel();

}

// MQTT消息处理器(消费者,用于服务端自发自收的测试)

@Bean

@ServiceActivator(inputChannel = CHANNEL_RECV)

public MessageHandler handler() {

return new MessageHandler() {

@Override

public void handleMessage(Message> message) throws MessagingException {

LOGGER.error("msg:{}", message.getPayload());

}

};

}

}

新增一个消息发送接口 IMqttSender 。

import com.hosh.tech.config.MqttConfig;

import org.springframework.integration.annotation.MessagingGateway;

import org.springframework.integration.mqtt.support.MqttHeaders;

import org.springframework.messaging.handler.annotation.Header;

import org.springframework.stereotype.Component;

/**

* MQTT生产者消息发送接口

* MessagingGateway要指定生产者的通道名称

*/

@Component

@MessagingGateway(defaultRequestChannel = MqttConfig.CHANNEL_SEND)

public interface IMqttSender {

/**

* 发送信息到MQTT服务器(实现发送全用户消息)

* @param data 消息内容

*/

void sendToMqtt(String data);

/**

* 发送信息到 MQTT 服务器(实现发送公告类消息——P2M)

* @param topic 主题

* @param payload 消息内容

*/

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

String payload);

/**

* 发送信息到 MQTT 服务器(实现发送点对点的消息)

* @param topic 主题

* @param qos 对消息处理的几种机制

* 0 表示的是订阅者没收到消息不会再次发送,消息会丢失

* 1 表示的是会尝试重试,一直到接收到消息,但这种情况可能导致订阅者收到多次重复消息

* 2 多了一次去重的动作,确保订阅者收到的消息有一次

* @param payload 消息内容

*/

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

@Header(MqttHeaders.QOS) int qos,

String payload);

}

测试 web 服务端的推送

web 服务端的发送消息的实现

4b4f26eb8137d226944a8f96338f2dd4.png

为了方便测试,消息为自发自收,收消息的实现已经在 MqttConfig 中给出

3eb9cfb4c06245c14ea4e6a0457ebb92.png

通过 http 请求触发自发自收的过程,可以看到如下的打印信息

e2d67a4f475a3070f850b62c9de980ea.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值