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);
}
}
}
});
}
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();
}
}
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);
}
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());
}
});
}
Aggregations