com.feingto.iot.server.handler.mqtt.PublishHandler Maven / Gradle / Ivy
package com.feingto.iot.server.handler.mqtt;
import com.feingto.iot.common.model.mqtt.ImSpan;
import com.feingto.iot.common.model.mqtt.SendMessage;
import com.feingto.iot.common.service.mqtt.MessageRequest;
import com.feingto.iot.common.service.mqtt.MessageResponse;
import com.feingto.iot.common.util.MessageId;
import com.feingto.iot.server.cache.MessageCache;
import com.feingto.iot.server.cache.RetainedCache;
import com.feingto.iot.server.cache.SessionCache;
import com.feingto.iot.server.cache.SubscribeCache;
import com.feingto.iot.server.handler.BaseMessageHandler;
import com.feingto.iot.server.serialize.JSON;
import com.feingto.iot.server.service.PushService;
import com.feingto.iot.server.util.Constants;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.*;
import lombok.extern.slf4j.Slf4j;
import java.util.Optional;
import java.util.UUID;
/**
* 消息发布处理器
*
* @author longfei
*/
@Slf4j
public class PublishHandler extends BaseMessageHandler {
private final PushService pushService;
public PublishHandler(PushService pushService) {
super(MqttMessageType.PUBLISH);
this.pushService = pushService;
}
@Override
public void handle(Channel channel, Object object) {
MqttPublishMessage msg = (MqttPublishMessage) object;
MqttFixedHeader fixedHeader = msg.fixedHeader();
MqttPublishVariableHeader variableHeader = msg.variableHeader();
SendMessage sendMessage = SendMessage.newInstance(msg);
// 存储每个Topic的最后一条保留消息及其Qos
if (sendMessage.retain()) {
log.debug(">>> save retain message on {}", sendMessage.topic());
RetainedCache.getInstance(igniteRetained).put(sendMessage.topic(), sendMessage);
}
sendMessage.retain(false);
// 推送到云端
this.storeOnCloud(channel, sendMessage);
switch (fixedHeader.qosLevel()) {
case AT_MOST_ONCE:
// 发布消息到所有订阅者
pushService.internalSend(sendMessage);
break;
case AT_LEAST_ONCE:
// 持久化消息
this.storeMessage(sendMessage, MqttMessageType.PUBLISH);
// 发布消息到所有订阅者
pushService.internalSend(sendMessage);
// 返回puback消息
MessageResponse.puback(channel, MqttMessageType.PUBACK, MqttQoS.AT_MOST_ONCE, variableHeader.packetId());
break;
case EXACTLY_ONCE:
// 持久化消息
this.storeMessage(sendMessage, MqttMessageType.PUBREC);
// 返回pubrec消息
MessageResponse.puback(channel, MqttMessageType.PUBREC, MqttQoS.AT_LEAST_ONCE, variableHeader.packetId());
break;
case FAILURE:
break;
}
}
/**
* 推送到云端
*/
private void storeOnCloud(Channel channel, SendMessage message) {
SubscribeCache.getInstance((igniteSubscribe)).findByTopic(Constants.TOPIC_STORE_ES)
.forEach(subscribe -> Optional.ofNullable(SessionCache.getInstance().get(subscribe.clientId()))
.ifPresent(sess -> MessageRequest.publish(sess.channel(), Constants.TOPIC_STORE_ES,
JSON.getInstance().obj2json(new ImSpan()
.id(UUID.randomUUID().toString() + "-" + MessageId.messageId())
.from(channel.attr(com.feingto.iot.common.Constants.KEY_CLIENT_ID).get())
.to(subscribe.clientId())
.topic(message.topic())
.payload(message.payload())
.timestamp(System.currentTimeMillis())), false, 0)));
}
/**
* 持久化消息
*/
private void storeMessage(SendMessage message, MqttMessageType type) {
SubscribeCache.getInstance((igniteSubscribe)).findByTopic(message.topic())
.forEach(subscribe -> MessageCache.getInstance(igniteMessage)
.put(subscribe.clientId(), message.type(type)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy