Search in sources :

Example 1 with SubscribeMateData

use of org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData in project mmqtt by MrHKing.

the class ClientActor method sendPublishMessage.

private void sendPublishMessage(String topic, MqttQoS mqttQoS, byte[] messageBytes, boolean retain, boolean dup, int messageId) {
    List<SubscribeMateData> subscribeStores = subscribeStoreService.search(topic);
    subscribeStores.forEach(subscribeStore -> {
        if (sessionStoreService.containsKey(subscribeStore.getClientId())) {
            // 订阅者收到MQTT消息的QoS级别, 最终取决于发布消息的QoS和主题订阅的QoS
            MqttQoS respQoS = mqttQoS.value() > subscribeStore.getMqttQoS() ? MqttQoS.valueOf(subscribeStore.getMqttQoS()) : mqttQoS;
            if (respQoS == MqttQoS.AT_MOST_ONCE) {
                MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(new MqttFixedHeader(MqttMessageType.PUBLISH, dup, respQoS, retain, 0), new MqttPublishVariableHeader(topic, 0), Unpooled.buffer().writeBytes(messageBytes));
                Loggers.BROKER_NOTIFIER.debug("PUBLISH - clientId: {}, topic: {}, Qos: {}", subscribeStore.getClientId(), topic, respQoS.value());
                SessionMateData sessionStore = sessionStoreService.get(subscribeStore.getClientId());
                if (sessionStore != null) {
                    sessionStore.getChannel().writeAndFlush(publishMessage);
                }
            }
            if (respQoS == MqttQoS.AT_LEAST_ONCE) {
                MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(new MqttFixedHeader(MqttMessageType.PUBLISH, dup, respQoS, retain, 0), new MqttPublishVariableHeader(topic, messageId), Unpooled.buffer().writeBytes(messageBytes));
                Loggers.BROKER_NOTIFIER.debug("PUBLISH - clientId: {}, topic: {}, Qos: {}, messageId: {}", subscribeStore.getClientId(), topic, respQoS.value(), messageId);
                DupPublishMessageMateData dupPublishMessageStore = new DupPublishMessageMateData().setClientId(subscribeStore.getClientId()).setTopic(topic).setMessageId(messageId).setMqttQoS(respQoS.value()).setMessageBytes(messageBytes);
                dupPublishMessageStoreService.put(subscribeStore.getClientId(), dupPublishMessageStore);
                SessionMateData sessionStore = sessionStoreService.get(subscribeStore.getClientId());
                if (sessionStore != null) {
                    sessionStore.getChannel().writeAndFlush(publishMessage);
                }
            }
            if (respQoS == MqttQoS.EXACTLY_ONCE) {
                MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(new MqttFixedHeader(MqttMessageType.PUBLISH, dup, respQoS, retain, 0), new MqttPublishVariableHeader(topic, messageId), Unpooled.buffer().writeBytes(messageBytes));
                Loggers.BROKER_NOTIFIER.debug("PUBLISH - clientId: {}, topic: {}, Qos: {}, messageId: {}", subscribeStore.getClientId(), topic, respQoS.value(), messageId);
                DupPublishMessageMateData dupPublishMessageStore = new DupPublishMessageMateData().setClientId(subscribeStore.getClientId()).setTopic(topic).setMessageId(messageId).setMqttQoS(respQoS.value()).setMessageBytes(messageBytes);
                dupPublishMessageStoreService.put(subscribeStore.getClientId(), dupPublishMessageStore);
                SessionMateData sessionStore = sessionStoreService.get(subscribeStore.getClientId());
                if (sessionStore != null) {
                    sessionStore.getChannel().writeAndFlush(publishMessage);
                }
            }
        }
    });
}
Also used : SessionMateData(org.monkey.mmq.core.actor.metadata.message.SessionMateData) DupPublishMessageMateData(org.monkey.mmq.core.actor.metadata.message.DupPublishMessageMateData) SubscribeMateData(org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData)

Example 2 with SubscribeMateData

use of org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData in project mmqtt by MrHKing.

the class Subscribe method processSubscribe.

public void processSubscribe(Channel channel, MqttSubscribeMessage msg) {
    List<MqttTopicSubscription> topicSubscriptions = msg.payload().topicSubscriptions();
    if (this.validTopicFilter(topicSubscriptions)) {
        String clientId = (String) channel.attr(AttributeKey.valueOf("clientId")).get();
        List<Integer> mqttQoSList = new ArrayList<Integer>();
        topicSubscriptions.forEach(topicSubscription -> {
            String topicFilter = topicSubscription.topicName();
            MqttQoS mqttQoS = topicSubscription.qualityOfService();
            SubscribeMateData subscribeStore = new SubscribeMateData(clientId, topicFilter, mqttQoS.value());
            try {
                subscribeStoreService.put(topicFilter, subscribeStore);
            } catch (MmqException e) {
                LoggerUtils.printIfDebugEnabled(Loggers.BROKER_PROTOCOL, "Subscribe - clientId: {}, subscribe: {}", channel.attr(AttributeKey.valueOf("clientId")).get(), topicFilter);
            }
            mqttQoSList.add(mqttQoS.value());
            LoggerUtils.printIfDebugEnabled(Loggers.BROKER_PROTOCOL, "SUBSCRIBE - clientId: {}, topFilter: {}, QoS: {}", clientId, topicFilter, mqttQoS.value());
        });
        MqttSubAckMessage subAckMessage = (MqttSubAckMessage) MqttMessageFactory.newMessage(new MqttFixedHeader(MqttMessageType.SUBACK, false, MqttQoS.AT_MOST_ONCE, false, 0), MqttMessageIdVariableHeader.from(msg.variableHeader().messageId()), new MqttSubAckPayload(mqttQoSList));
        channel.writeAndFlush(subAckMessage);
        // 发布保留消息
        topicSubscriptions.forEach(topicSubscription -> {
            String topicFilter = topicSubscription.topicName();
            MqttQoS mqttQoS = topicSubscription.qualityOfService();
            this.sendRetainMessage(channel, topicFilter, mqttQoS, msg.variableHeader().messageId());
        });
    } else {
        channel.close();
    }
}
Also used : MmqException(org.monkey.mmq.core.exception.MmqException) ArrayList(java.util.ArrayList) SubscribeMateData(org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData)

Example 3 with SubscribeMateData

use of org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData in project mmqtt by MrHKing.

the class SubscribeStoreService method onChange.

@Override
public void onChange(String key, SubscribeMateData value) throws Exception {
    if (StrUtil.contains(value.getTopicFilter(), '#') || StrUtil.contains(value.getTopicFilter(), '+')) {
        ConcurrentHashMap<String, SubscribeMateData> clientConcurrentHashMap = subWildcard.get(value.getTopicFilter());
        if (clientConcurrentHashMap == null) {
            clientConcurrentHashMap = new ConcurrentHashMap<>();
        }
        clientConcurrentHashMap.put(key, value);
        subWildcard.put(value.getTopicFilter(), clientConcurrentHashMap);
    } else {
        ConcurrentHashMap<String, SubscribeMateData> clientConcurrentHashMap = subscribes.get(value.getTopicFilter());
        if (clientConcurrentHashMap == null) {
            clientConcurrentHashMap = new ConcurrentHashMap<>();
        }
        clientConcurrentHashMap.put(key, value);
        subscribes.put(value.getTopicFilter(), clientConcurrentHashMap);
    }
    AtomicInteger subCount = new AtomicInteger();
    subscribes.forEach((subKey, client) -> {
        subCount.addAndGet(client.size());
    });
    subWildcard.forEach((subKey, client) -> {
        subCount.addAndGet(client.size());
    });
    SystemInfoMateData systemInfoMateData = systemInfoStoreService.getSystemInfo();
    systemInfoMateData.setSubscribeCount(subCount.get());
    systemInfoStoreService.put(systemInfoMateData);
}
Also used : SystemInfoMateData(org.monkey.mmq.core.actor.metadata.system.SystemInfoMateData) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SubscribeMateData(org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData)

Example 4 with SubscribeMateData

use of org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData in project mmqtt by MrHKing.

the class Publish method sendPublishMessage.

private void sendPublishMessage(String clientId, String topic, MqttQoS mqttQoS, byte[] messageBytes, boolean retain, boolean dup, int packetId, Channel channel) {
    List<SubscribeMateData> subscribeStores = subscribeStoreService.search(topic);
    subscribeStores.forEach(subscribeStore -> {
        // 订阅者收到MQTT消息的QoS级别, 最终取决于发布消息的QoS和主题订阅的QoS
        MqttQoS respQoS = mqttQoS.value() > subscribeStore.getMqttQoS() ? MqttQoS.valueOf(subscribeStore.getMqttQoS()) : mqttQoS;
        SessionMateData sessionStore = sessionStoreService.get(subscribeStore.getClientId());
        if (sessionStore != null && this.local.getIp().equals(subscribeStore.getNodeIp()) && subscribeStore.getNodePort() == this.local.getPort()) {
            if (respQoS == MqttQoS.AT_MOST_ONCE) {
                MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(new MqttFixedHeader(MqttMessageType.PUBLISH, dup, respQoS, retain, 0), new MqttPublishVariableHeader(topic, packetId), Unpooled.buffer().writeBytes(messageBytes));
                LoggerUtils.printIfDebugEnabled(Loggers.BROKER_PROTOCOL, "PUBLISH - clientId: {}, topic: {}, Qos: {}", subscribeStore.getClientId(), topic, respQoS.value());
                sessionStore.getChannel().writeAndFlush(publishMessage);
            }
            if (respQoS == MqttQoS.AT_LEAST_ONCE) {
                MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(new MqttFixedHeader(MqttMessageType.PUBLISH, dup, respQoS, retain, 0), new MqttPublishVariableHeader(topic, packetId), Unpooled.buffer().writeBytes(messageBytes));
                LoggerUtils.printIfDebugEnabled(Loggers.BROKER_PROTOCOL, "PUBLISH - clientId: {}, topic: {}, Qos: {}, messageId: {}", subscribeStore.getClientId(), topic, respQoS.value(), packetId);
                DupPublishMessageMateData dupPublishMessageStore = new DupPublishMessageMateData().setClientId(subscribeStore.getClientId()).setTopic(topic).setMqttQoS(respQoS.value()).setMessageId(packetId).setMessageBytes(messageBytes);
                dupPublishMessageStoreService.put(subscribeStore.getClientId(), dupPublishMessageStore);
                sessionStore.getChannel().writeAndFlush(publishMessage);
            }
            if (respQoS == MqttQoS.EXACTLY_ONCE) {
                MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(new MqttFixedHeader(MqttMessageType.PUBLISH, dup, respQoS, retain, 0), new MqttPublishVariableHeader(topic, packetId), Unpooled.buffer().writeBytes(messageBytes));
                LoggerUtils.printIfDebugEnabled(Loggers.BROKER_PROTOCOL, "PUBLISH - clientId: {}, topic: {}, Qos: {}, messageId: {}", subscribeStore.getClientId(), topic, respQoS.value(), packetId);
                DupPublishMessageMateData dupPublishMessageStore = new DupPublishMessageMateData().setClientId(subscribeStore.getClientId()).setTopic(topic).setMqttQoS(respQoS.value()).setMessageId(packetId).setMessageBytes(messageBytes);
                dupPublishMessageStoreService.put(subscribeStore.getClientId(), dupPublishMessageStore);
                sessionStore.getChannel().writeAndFlush(publishMessage);
            }
        } else {
            PublishMessage publishMessage = new PublishMessage();
            publishMessage.setNodeIp(subscribeStore.getNodeIp());
            publishMessage.setNodePort(subscribeStore.getNodePort());
            publishMessage.setInternalMessage(InternalMessage.newBuilder().setTopic(topic).setMqttQoS(respQoS.value()).setClientId(subscribeStore.getClientId()).setMessageBytes(ByteString.copyFrom(messageBytes)).setDup(false).setRetain(false).setMessageId(packetId).build());
            ActorSelection actorSelection = actorSystem.actorSelection("/user/" + clientId);
            actorSelection.tell(publishMessage, ActorRef.noSender());
        }
    });
}
Also used : PublishMessage(org.monkey.mmq.core.actor.message.PublishMessage) ActorSelection(akka.actor.ActorSelection) SessionMateData(org.monkey.mmq.core.actor.metadata.message.SessionMateData) DupPublishMessageMateData(org.monkey.mmq.core.actor.metadata.message.DupPublishMessageMateData) SubscribeMateData(org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData)

Aggregations

SubscribeMateData (org.monkey.mmq.core.actor.metadata.subscribe.SubscribeMateData)4 DupPublishMessageMateData (org.monkey.mmq.core.actor.metadata.message.DupPublishMessageMateData)2 SessionMateData (org.monkey.mmq.core.actor.metadata.message.SessionMateData)2 ActorSelection (akka.actor.ActorSelection)1 ArrayList (java.util.ArrayList)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 PublishMessage (org.monkey.mmq.core.actor.message.PublishMessage)1 SystemInfoMateData (org.monkey.mmq.core.actor.metadata.system.SystemInfoMateData)1 MmqException (org.monkey.mmq.core.exception.MmqException)1