From ca6918e12cd67dc49be64f32732438e7b8d6dba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Tue, 7 Mar 2023 22:06:33 +0800 Subject: [PATCH 01/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../smartboot/mqtt/common/InflightQueue.java | 78 ++++++++----------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index b2e5d444..cc1e996c 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -3,9 +3,6 @@ package org.smartboot.mqtt.common; import org.smartboot.mqtt.common.message.MqttPublishMessage; import org.smartboot.mqtt.common.util.ValidateUtils; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; - /** * @author 三刀(zhengjunweimail@163.com) * @version V1.0 , 2022/4/26 @@ -16,9 +13,6 @@ public class InflightQueue { private int takeIndex; private int putIndex; private int count; - private final ReentrantLock lock = new ReentrantLock(false); - - private final Condition notFull = lock.newCondition(); public InflightQueue(int size) { ValidateUtils.isTrue(size > 0, "inflight must >0"); @@ -26,51 +20,43 @@ public class InflightQueue { this.offsets = new long[size]; } - public int offer(MqttPublishMessage mqttMessage, long offset) { - lock.lock(); - try { - if (count == queue.length) { - return -1; - } - queue[putIndex] = mqttMessage; - offsets[putIndex] = offset; - int index = putIndex++; - if (putIndex == queue.length) { - putIndex = 0; - } - count++; - return index; - } finally { - lock.unlock(); + public synchronized int offer(MqttPublishMessage mqttMessage, long offset) { + if (count == queue.length) { + return -1; + } + queue[putIndex] = mqttMessage; + offsets[putIndex] = offset; + int index = putIndex++; + if (putIndex == queue.length) { + putIndex = 0; } + count++; + return index; } - public long commit(int commitIndex) { - lock.lock(); - try { - if (commitIndex != takeIndex) { - //转负数表示以提交 - offsets[commitIndex] = offsets[commitIndex] | Long.MIN_VALUE; - return -1; - } - long offset = offsets[takeIndex++]; - count--; + public synchronized long commit(int commitIndex) { + if (commitIndex != takeIndex) { + //转负数表示以提交 + offsets[commitIndex] = offsets[commitIndex] | Long.MIN_VALUE; + return -1; + } + long offset = offsets[takeIndex]; + offsets[takeIndex] = 0; + queue[takeIndex++] = null; + count--; + if (takeIndex == queue.length) { + takeIndex = 0; + } + while (count > 0 && offsets[takeIndex] < 0) { + offset = offsets[takeIndex] & ~Long.MIN_VALUE; + offsets[takeIndex] = 0; + queue[takeIndex++] = null; if (takeIndex == queue.length) { takeIndex = 0; } - while (count > 0 && offsets[takeIndex] < 0) { - offset = offsets[takeIndex] & ~Long.MIN_VALUE; - offsets[takeIndex] = 0; - queue[takeIndex++] = null; - if (takeIndex == queue.length) { - takeIndex = 0; - } - count--; - } - notFull.signal(); - return offset; - } finally { - lock.unlock(); + count--; } + System.out.println("offset:" + offset); + return offset; } -} +} \ No newline at end of file -- Gitee From 87812315defaf944d6f9ea02a249d8bf58731d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Tue, 7 Mar 2023 22:07:01 +0800 Subject: [PATCH 02/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/smartboot/mqtt/common/InflightQueue.java | 1 - 1 file changed, 1 deletion(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index cc1e996c..b374e47c 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -56,7 +56,6 @@ public class InflightQueue { } count--; } - System.out.println("offset:" + offset); return offset; } } \ No newline at end of file -- Gitee From dfa3753a2a1f7ec18d00417b36970ad3f4a0017c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Tue, 7 Mar 2023 22:34:29 +0800 Subject: [PATCH 03/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/smartboot/mqtt/client/MqttClient.java | 2 +- .../smartboot/mqtt/common/QosPublisher.java | 2 +- .../common/enums/QosCallbackTypeEnum.java | 94 ------------------- .../variable/MqttPublishVariableHeader.java | 3 +- .../smartboot/mqtt/common/util/MqttUtil.java | 9 ++ 5 files changed, 13 insertions(+), 97 deletions(-) delete mode 100644 smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/enums/QosCallbackTypeEnum.java diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java index e5f3c80a..3b46c3f0 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java @@ -412,7 +412,7 @@ public class MqttClient extends AbstractSession { } } - }, false); + }, true); } public MqttClientConfigure getClientConfigure() { diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java index 15ca5c73..28d37f17 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java @@ -68,8 +68,8 @@ public abstract class QosPublisher { retry(pubRelFuture, session, pubRelMessage); session.write(pubRelMessage); })); - session.write(publishMessage, false); retry(publishFuture, session, publishMessage); + session.write(publishMessage, autoFlush); } protected abstract void retry(CompletableFuture future, AbstractSession session, MqttMessage mqttMessage); diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/enums/QosCallbackTypeEnum.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/enums/QosCallbackTypeEnum.java deleted file mode 100644 index 0b0c8ab3..00000000 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/enums/QosCallbackTypeEnum.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.smartboot.mqtt.common.enums; - -/** - * @author qinluo - * @date 2022-04-11 16:30:57 - * @since 1.0.0 - */ -public enum QosCallbackTypeEnum { - - /** - * QosLevel 1. (server -> client) - */ - PUBACK(1, MqttMessageType.PUBACK.value(), 0, null), - - /* - * PUBLISH QosLevel 2 (client -> server) - * - */ - - /** - * QosLevel 2 (server -> client) - */ - PUBREC(2, MqttMessageType.PUBREC.value(), 0, null), - - /** - * QosLevel 2 (client -> server) - */ - PUBREL(3, MqttMessageType.PUBREL.value(), 1, null), - - /** - * QosLevel 2 (server -> client) - */ - PUBCOMP(4, MqttMessageType.PUBCOMP.value(), 0, null), - - ; - - static { - PUBREC.next = PUBREL; - PUBREL.next = PUBCOMP; - } - - private final int type; - private final int msgType; - private final int waitSide; - private QosCallbackTypeEnum next; - - QosCallbackTypeEnum(int type, int msgType, int waitSide, QosCallbackTypeEnum next) { - this.type = type; - this.msgType = msgType; - this.waitSide = waitSide; - this.next = next; - } - - public int getType() { - return type; - } - - public int getMsgType() { - return msgType; - } - - public int getWaitSide() { - return waitSide; - } - - public static QosCallbackTypeEnum getInstance(int type) { - for (QosCallbackTypeEnum instance : values()) { - if (instance.type == type) { - return instance; - } - } - - return null; - } - - public static QosCallbackTypeEnum next(int type, int side) { - QosCallbackTypeEnum instance = getInstance(type); - if (instance == null) { - return null; - } - - instance = instance.next; - - while (instance != null) { - if (instance.waitSide == side) { - return instance; - } - instance = instance.next; - } - - return null; - - } -} diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPublishVariableHeader.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPublishVariableHeader.java index 06f5f083..3e17d8d8 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPublishVariableHeader.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPublishVariableHeader.java @@ -3,6 +3,7 @@ package org.smartboot.mqtt.common.message.variable; import org.smartboot.mqtt.common.MqttWriter; import org.smartboot.mqtt.common.message.MqttCodecUtil; import org.smartboot.mqtt.common.message.variable.properties.PublishProperties; +import org.smartboot.mqtt.common.util.MqttUtil; import java.io.IOException; @@ -31,7 +32,7 @@ public class MqttPublishVariableHeader extends MqttPacketIdVariableHeader 0 ? 2 : 0; - topicNameBytes = MqttCodecUtil.encodeUTF8(topicName); + topicNameBytes = MqttUtil.encodeCache(topicName); length += topicNameBytes.length; return length; } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/util/MqttUtil.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/util/MqttUtil.java index 42428f63..de90f3ed 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/util/MqttUtil.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/util/MqttUtil.java @@ -3,8 +3,11 @@ package org.smartboot.mqtt.common.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smartboot.mqtt.common.AbstractSession; +import org.smartboot.mqtt.common.message.MqttCodecUtil; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; /** * @author 三刀(zhengjunweimail@163.com) @@ -17,6 +20,8 @@ public class MqttUtil { */ private static final char[] TOPIC_WILDCARDS = {'#', '+'}; + private static final Map cache = new ConcurrentHashMap<>(); + public static boolean containsTopicWildcards(String topicName) { for (char c : TOPIC_WILDCARDS) { if (topicName.indexOf(c) >= 0) { @@ -38,4 +43,8 @@ public class MqttUtil { return ""; } } + + public static byte[] encodeCache(String topicName) { + return cache.computeIfAbsent(topicName, s -> MqttCodecUtil.encodeUTF8(topicName)); + } } -- Gitee From 749644f795650a9bbb3213418232f417ffabb3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Thu, 9 Mar 2023 19:03:15 +0800 Subject: [PATCH 04/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/broker/BrokerContextImpl.java | 20 +++++++------------ .../smartboot/mqtt/broker/BrokerTopic.java | 11 ++++------ .../mqtt/client/MqttClientProcessor.java | 20 +++++++++---------- 3 files changed, 21 insertions(+), 30 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java index 24852427..12cd4aed 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java @@ -271,7 +271,7 @@ public class BrokerContextImpl implements BrokerContext { //存在待输出消息 Collection subscribers = brokerTopic.getConsumeOffsets().values(); subscribers.stream().filter(topicSubscriber -> topicSubscriber.isReady() && topicSubscriber.getPushVersion() != brokerTopic.getVersion().get()).forEach(topicSubscriber -> topicSubscriber.batchPublish(BrokerContextImpl.this)); - brokerTopic.setPushing(false); + brokerTopic.getSemaphore().release(); for (TopicSubscriber subscriber : subscribers) { if (subscriber.getPushVersion() != brokerTopic.getVersion().get()) { notifyPush(brokerTopic); @@ -375,20 +375,14 @@ public class BrokerContextImpl implements BrokerContext { } private void notifyPush(BrokerTopic topic) { - if (topic.isPushing()) { + if (!topic.getSemaphore().tryAcquire()) { return; } - synchronized (topic) { - //已加入推送队列 - if (topic.isPushing()) { - return; - } - try { - topic.setPushing(true); - pushTopicQueue.put(topic); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + //已加入推送队列 + try { + pushTopicQueue.put(topic); + } catch (InterruptedException e) { + throw new RuntimeException(e); } } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java index aa646f31..357a7f9f 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java @@ -4,6 +4,7 @@ import org.smartboot.mqtt.common.Topic; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; /** @@ -21,7 +22,7 @@ public class BrokerTopic extends Topic { /** * 当前Topic是否圈闭推送完成 */ - private boolean pushing; + private final Semaphore semaphore = new Semaphore(1); public BrokerTopic(String topic) { super(topic); @@ -35,11 +36,7 @@ public class BrokerTopic extends Topic { return version; } - public boolean isPushing() { - return pushing; - } - - public void setPushing(boolean pushing) { - this.pushing = pushing; + public Semaphore getSemaphore() { + return semaphore; } } diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClientProcessor.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClientProcessor.java index cfc786a2..798f3c32 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClientProcessor.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClientProcessor.java @@ -32,24 +32,24 @@ import java.util.Map; public class MqttClientProcessor extends AbstractMessageProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(MqttClientProcessor.class); private final MqttClient mqttClient; - private final Map, MqttProcessor> processorMap = new HashMap<>(); + private static final Map, MqttProcessor> processors = new HashMap<>(); public MqttClientProcessor(MqttClient mqttClient) { this.mqttClient = mqttClient; - processorMap.put(MqttConnAckMessage.class, new ConnAckProcessor()); - processorMap.put(MqttPubAckMessage.class, new MqttAckProcessor()); - processorMap.put(MqttPublishMessage.class, new PublishProcessor()); - processorMap.put(MqttPubRecMessage.class, new MqttAckProcessor()); - processorMap.put(MqttPubCompMessage.class, new MqttAckProcessor()); - processorMap.put(MqttPubRelMessage.class, new MqttAckProcessor()); - processorMap.put(MqttSubAckMessage.class, new MqttAckProcessor()); - processorMap.put(MqttPingRespMessage.class, new MqttPingRespProcessor()); + processors.put(MqttConnAckMessage.class, new ConnAckProcessor()); + processors.put(MqttPubAckMessage.class, new MqttAckProcessor()); + processors.put(MqttPublishMessage.class, new PublishProcessor()); + processors.put(MqttPubRecMessage.class, new MqttAckProcessor()); + processors.put(MqttPubCompMessage.class, new MqttAckProcessor()); + processors.put(MqttPubRelMessage.class, new MqttAckProcessor()); + processors.put(MqttSubAckMessage.class, new MqttAckProcessor()); + processors.put(MqttPingRespMessage.class, new MqttPingRespProcessor()); } @Override public void process0(AioSession session, MqttMessage msg) { mqttClient.getEventBus().publish(EventType.RECEIVE_MESSAGE, EventObject.newEventObject(mqttClient, msg)); - MqttProcessor processor = processorMap.get(msg.getClass()); + MqttProcessor processor = processors.get(msg.getClass()); // LOGGER.info("receive msg:{}", msg); if (processor != null) { processor.process(mqttClient, msg); -- Gitee From 502bfdd5e171e8d491f364929b793cb4bdd58ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Thu, 9 Mar 2023 19:58:47 +0800 Subject: [PATCH 05/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/smartboot/mqtt/client/MqttClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java index 3b46c3f0..669c3568 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java @@ -57,7 +57,7 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; public class MqttClient extends AbstractSession { - private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + private static final Logger LOGGER = LoggerFactory.getLogger(MqttClient.class); /** * 客户端配置项 */ -- Gitee From 67a3deaa8d9475c75a98b3858724317234b84b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Thu, 9 Mar 2023 21:37:47 +0800 Subject: [PATCH 06/29] =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E7=BB=84=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/broker/BrokerContextImpl.java | 14 +++++++++- .../mqtt/broker/openapi/OpenApiPlugin.java | 26 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java index 12cd4aed..d03f3e46 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java @@ -36,6 +36,7 @@ import org.smartboot.mqtt.common.to.MetricItemTO; import org.smartboot.mqtt.common.util.MqttUtil; import org.smartboot.mqtt.common.util.ValidateUtils; import org.smartboot.socket.buffer.BufferPagePool; +import org.smartboot.socket.enhance.EnhanceAsynchronousChannelProvider; import org.smartboot.socket.extension.plugins.AbstractPlugin; import org.smartboot.socket.transport.AioQuickServer; import org.smartboot.socket.transport.AioSession; @@ -44,6 +45,7 @@ import org.yaml.snakeyaml.Yaml; import java.io.IOException; import java.io.InputStream; import java.lang.management.ManagementFactory; +import java.nio.channels.AsynchronousChannelGroup; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -109,6 +111,7 @@ public class BrokerContextImpl implements BrokerContext { * 统计指标 */ private final Map metricMap = new HashMap<>(); + private AsynchronousChannelGroup asynchronousChannelGroup; @Override public void init() throws IOException { @@ -129,10 +132,18 @@ public class BrokerContextImpl implements BrokerContext { try { + asynchronousChannelGroup = new EnhanceAsynchronousChannelProvider(false).openAsynchronousChannelGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactory() { + int i; + + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "smart-mqtt-broker-" + (++i)); + } + }); pagePool = new BufferPagePool(10 * 1024 * 1024, brokerConfigure.getThreadNum(), true); server = new AioQuickServer(brokerConfigure.getHost(), brokerConfigure.getPort(), new MqttProtocol(brokerConfigure.getMaxPacketSize()), processor); server.setBannerEnabled(false).setReadBufferSize(brokerConfigure.getBufferSize()).setWriteBuffer(brokerConfigure.getBufferSize(), Math.min(brokerConfigure.getMaxInflight(), 16)).setBufferPagePool(pagePool).setThreadNum(Math.max(2, brokerConfigure.getThreadNum())); - server.start(); + server.start(asynchronousChannelGroup); System.out.println(BrokerConfigure.BANNER + "\r\n :: smart-mqtt broker" + "::\t(" + BrokerConfigure.VERSION + ")"); System.out.println("❤️Gitee: https://gitee.com/smartboot/smart-mqtt"); System.out.println("Github: https://github.com/smartboot/smart-mqtt"); @@ -567,6 +578,7 @@ public class BrokerContextImpl implements BrokerContext { pushTopicQueue.offer(SHUTDOWN_TOPIC); pushThreadPool.shutdown(); server.shutdown(); + asynchronousChannelGroup.shutdown(); pagePool.release(); //卸载插件 plugins.forEach(Plugin::uninstall); diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/openapi/OpenApiPlugin.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/openapi/OpenApiPlugin.java index c141992e..45d55b5f 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/openapi/OpenApiPlugin.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/openapi/OpenApiPlugin.java @@ -11,6 +11,10 @@ import org.smartboot.mqtt.broker.openapi.controller.DashBoardController; import org.smartboot.mqtt.broker.openapi.controller.SubscriptionController; import org.smartboot.mqtt.broker.plugin.Plugin; import org.smartboot.mqtt.broker.plugin.PluginException; +import org.smartboot.socket.enhance.EnhanceAsynchronousChannelProvider; + +import java.nio.channels.AsynchronousChannelGroup; +import java.util.concurrent.ThreadFactory; /** * @author 三刀(zhengjunweimail@163.com) @@ -19,6 +23,9 @@ import org.smartboot.mqtt.broker.plugin.PluginException; public class OpenApiPlugin extends Plugin { private static final Logger LOGGER = LoggerFactory.getLogger(OpenApiPlugin.class); private static final String CONFIG_JSON_PATH = "$['broker']['openapi']"; + private RestfulBootstrap restfulBootstrap; + + private AsynchronousChannelGroup asynchronousChannelGroup; @Override protected void initPlugin(BrokerContext brokerContext) { @@ -28,7 +35,15 @@ public class OpenApiPlugin extends Plugin { return; } try { - RestfulBootstrap restfulBootstrap = RestfulBootstrap.getInstance(new StaticResourceHandler()); + asynchronousChannelGroup = new EnhanceAsynchronousChannelProvider(false).openAsynchronousChannelGroup(Runtime.getRuntime().availableProcessors(), new ThreadFactory() { + int i; + + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "openApi-" + (++i)); + } + }); + restfulBootstrap = RestfulBootstrap.getInstance(new StaticResourceHandler()); restfulBootstrap.inspect((httpRequest, response) -> { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Headers", "*"); @@ -39,7 +54,8 @@ public class OpenApiPlugin extends Plugin { HttpBootstrap bootstrap = restfulBootstrap.bootstrap(); bootstrap.setPort(config.getPort()); - bootstrap.configuration().bannerEnabled(false).host(config.getHost()).readBufferSize(1024 * 8); + bootstrap.configuration().bannerEnabled(false).host(config.getHost()).readBufferSize(1024 * 8).group(asynchronousChannelGroup); + bootstrap.start(); brokerContext.getProviders().setOpenApiBootStrap(restfulBootstrap); LOGGER.info("openapi server start success!"); @@ -48,4 +64,10 @@ public class OpenApiPlugin extends Plugin { throw new PluginException("start openapi exception"); } } + + @Override + protected void destroyPlugin() { + restfulBootstrap.bootstrap().shutdown(); + asynchronousChannelGroup.shutdown(); + } } -- Gitee From c0bd183123a1dd48f2b15c0507098d205fdb1070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Thu, 9 Mar 2023 22:00:27 +0800 Subject: [PATCH 07/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/smartboot/mqtt/broker/BrokerQosPublisher.java | 5 ++++- .../main/java/org/smartboot/mqtt/common/QosPublisher.java | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java index 28f825d6..99d73ad0 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java @@ -1,5 +1,7 @@ package org.smartboot.mqtt.broker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.smartboot.mqtt.common.AbstractSession; import org.smartboot.mqtt.common.AsyncTask; import org.smartboot.mqtt.common.QosPublisher; @@ -14,6 +16,7 @@ import java.util.concurrent.TimeUnit; * @version V1.0 , 2022/4/25 */ public class BrokerQosPublisher extends QosPublisher { + private static final Logger LOGGER = LoggerFactory.getLogger(BrokerQosPublisher.class); private final BrokerContext mqttContext; public BrokerQosPublisher(BrokerContext mqttContext) { @@ -28,7 +31,7 @@ public class BrokerQosPublisher extends QosPublisher { public void execute() { if (!future.isDone()) { // 如果客户端发生过断链,则 mqttSession!=session - System.out.println("retry..."); + LOGGER.info("retry..."); MqttSession mqttSession = mqttContext.getSession(session.getClientId()); mqttSession.write(mqttMessage); } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java index 28d37f17..47a0f8fe 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java @@ -61,7 +61,6 @@ public abstract class QosPublisher { ValidateUtils.isTrue(compMessage.getFixedHeader().getMessageType() == MqttMessageType.PUBCOMP, "invalid message type"); ValidateUtils.isTrue(Objects.equals(compMessage.getVariableHeader().getPacketId(), pubRelMessage.getVariableHeader().getPacketId()), "invalid packetId"); pubRelFuture.complete(true); - LOGGER.info("Qos2消息发送成功..."); consumer.accept(compMessage.getVariableHeader().getPacketId()); })); //注册重试 -- Gitee From bd52c4063e39c704e420ccd5a695dc6d047353fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 10 Mar 2023 19:22:52 +0800 Subject: [PATCH 08/29] =?UTF-8?q?=E5=86=85=E5=AD=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/common/MqttMessageBuilders.java | 4 +- .../mqtt/common/message/MqttCodecUtil.java | 6 +-- .../mqtt/common/message/MqttFixedHeader.java | 12 ++---- .../mqtt/common/message/MqttMessage.java | 11 ++++++ .../common/message/MqttPubQosMessage.java | 4 +- .../common/message/MqttPublishMessage.java | 2 +- .../common/message/MqttSubAckMessage.java | 2 +- .../common/message/MqttSubscribeMessage.java | 2 +- .../message/MqttUnsubscribeMessage.java | 2 +- .../common/protocol/MqttMessageFactory.java | 37 +++++++++++++++++++ .../mqtt/common/protocol/MqttProtocol.java | 28 +++++--------- 11 files changed, 70 insertions(+), 40 deletions(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java index 52763a85..13f647f9 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java @@ -79,7 +79,7 @@ public final class MqttMessageBuilders { } public MqttPublishMessage build() { - MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, retained, 0); + MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, retained); if (qos != MqttQoS.AT_LEAST_ONCE && qos != MqttQoS.EXACTLY_ONCE) { packetId = -1; } @@ -119,7 +119,7 @@ public final class MqttMessageBuilders { } public MqttSubscribeMessage build() { - MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.SUBSCRIBE, false, MqttQoS.AT_LEAST_ONCE, false, 0); + MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.SUBSCRIBE, false, MqttQoS.AT_LEAST_ONCE, false); MqttSubscribePayload mqttSubscribePayload = new MqttSubscribePayload(); mqttSubscribePayload.setTopicSubscriptions(subscriptions); MqttSubscribeVariableHeader variableHeader = new MqttSubscribeVariableHeader(packetId, subscribeProperties); diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java index f1ccc67d..05746dc1 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java @@ -39,8 +39,7 @@ public final class MqttCodecUtil { mqttFixedHeader.getMessageType(), false, MqttQoS.AT_MOST_ONCE, - false, - mqttFixedHeader.remainingLength()); + false); } return mqttFixedHeader; case PUBREL: @@ -51,8 +50,7 @@ public final class MqttCodecUtil { mqttFixedHeader.getMessageType(), mqttFixedHeader.isDup(), mqttFixedHeader.getQosLevel(), - false, - mqttFixedHeader.remainingLength()); + false); } return mqttFixedHeader; default: diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java index 4da49d2d..a52b741d 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java @@ -26,6 +26,7 @@ public class MqttFixedHeader { public static final MqttFixedHeader PUB_REC_HEADER = new MqttFixedHeader(MqttMessageType.PUBREC, MqttQoS.AT_MOST_ONCE); public static final MqttFixedHeader PUB_REL_HEADER = new MqttFixedHeader(MqttMessageType.PUBREL, MqttQoS.AT_LEAST_ONCE); public static final MqttFixedHeader PUB_COMP_HEADER = new MqttFixedHeader(MqttMessageType.PUBCOMP, MqttQoS.AT_MOST_ONCE); + public static final MqttFixedHeader SUBSCRIBE_HEADER = new MqttFixedHeader(MqttMessageType.SUBSCRIBE, MqttQoS.AT_LEAST_ONCE); public static final MqttFixedHeader SUB_ACK_HEADER = new MqttFixedHeader(MqttMessageType.SUBACK, MqttQoS.AT_MOST_ONCE); public static final MqttFixedHeader UNSUBSCRIBE_HEADER = new MqttFixedHeader(MqttMessageType.UNSUBSCRIBE, MqttQoS.AT_LEAST_ONCE); public static final MqttFixedHeader UNSUB_ACK_HEADER = new MqttFixedHeader(MqttMessageType.UNSUBACK, MqttQoS.AT_MOST_ONCE); @@ -42,18 +43,16 @@ public class MqttFixedHeader { * 保留标志,是否存储消息 */ private final boolean retain; - private final int remainingLength; - public MqttFixedHeader(MqttMessageType messageType, boolean dup, MqttQoS qosLevel, boolean retain, int remainingLength) { + public MqttFixedHeader(MqttMessageType messageType, boolean dup, MqttQoS qosLevel, boolean retain) { this.messageType = messageType; this.dup = dup; this.qosLevel = qosLevel; this.retain = retain; - this.remainingLength = remainingLength; } public MqttFixedHeader(MqttMessageType messageType, MqttQoS qosLevel) { - this(messageType, false, qosLevel, false, 0); + this(messageType, false, qosLevel, false); } public MqttMessageType getMessageType() { @@ -71,9 +70,4 @@ public class MqttFixedHeader { public boolean isRetain() { return retain; } - - public int remainingLength() { - return remainingLength; - } - } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttMessage.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttMessage.java index a1abe667..b3c21fb9 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttMessage.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttMessage.java @@ -32,6 +32,10 @@ public abstract class MqttMessage extends ToString { */ protected final MqttFixedHeader fixedHeader; protected MqttVersion version; + /** + * 剩余长度 + */ + private int remainingLength; public MqttMessage(MqttFixedHeader mqttFixedHeader) { this.fixedHeader = mqttFixedHeader; @@ -84,6 +88,13 @@ public abstract class MqttMessage extends ToString { return messageId; } + public int getRemainingLength() { + return remainingLength; + } + + public void setRemainingLength(int remainingLength) { + this.remainingLength = remainingLength; + } public final MqttVersion getVersion() { return version; diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPubQosMessage.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPubQosMessage.java index 6e9ca561..ee919235 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPubQosMessage.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPubQosMessage.java @@ -28,11 +28,11 @@ public class MqttPubQosMessage extends MqttPacketIdentifierMessage 2) { + if (getRemainingLength() > 2) { reasonCode = buffer.get(); } //如果剩余长度小于4,则表示没有属性长度字段。 - if (fixedHeader.remainingLength() >= 4) { + if (getRemainingLength() >= 4) { ReasonProperties properties = new ReasonProperties(); properties.decode(buffer); header = new MqttPubQosVariableHeader(packetId, properties); diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPublishMessage.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPublishMessage.java index 7e32b4f2..21728845 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPublishMessage.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttPublishMessage.java @@ -53,7 +53,7 @@ public class MqttPublishMessage extends MqttVariableMessage grantedQos = new ArrayList(); int limit = buffer.limit(); buffer.limit(buffer.position() + payloadLength); diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttSubscribeMessage.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttSubscribeMessage.java index eda1761a..2132b532 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttSubscribeMessage.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttSubscribeMessage.java @@ -47,7 +47,7 @@ public class MqttSubscribeMessage extends MqttPacketIdentifierMessage subscribeTopics = new ArrayList<>(); - int payloadLength = fixedHeader.remainingLength() - getVariableHeaderLength(); + int payloadLength = getRemainingLength() - getVariableHeaderLength(); ValidateUtils.isTrue(buffer.remaining() >= payloadLength, "数据不足"); int limit = buffer.limit(); buffer.limit(buffer.position() + payloadLength); diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttUnsubscribeMessage.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttUnsubscribeMessage.java index b8e637e2..53c142bd 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttUnsubscribeMessage.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttUnsubscribeMessage.java @@ -48,7 +48,7 @@ public class MqttUnsubscribeMessage extends MqttPacketIdentifierMessage unsubscribeTopics = new ArrayList(); - int payloadLength = fixedHeader.remainingLength() - getVariableHeaderLength(); + int payloadLength = getRemainingLength() - getVariableHeaderLength(); int limit = buffer.limit(); buffer.limit(buffer.position() + payloadLength); while (buffer.hasRemaining()) { diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java index 968857aa..d486f672 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java @@ -1,5 +1,7 @@ package org.smartboot.mqtt.common.protocol; +import org.smartboot.mqtt.common.enums.MqttMessageType; +import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.message.MqttConnAckMessage; import org.smartboot.mqtt.common.message.MqttConnectMessage; import org.smartboot.mqtt.common.message.MqttDisconnectMessage; @@ -22,6 +24,41 @@ final class MqttMessageFactory { private MqttMessageFactory() { } + public static MqttFixedHeader newMqttFixedHeader(MqttMessageType messageType, boolean dup, int qosLevel, boolean retain) { + switch (messageType) { + case CONNECT: + return MqttFixedHeader.CONNECT_HEADER; + case CONNACK: + return MqttFixedHeader.CONN_ACK_HEADER; + case SUBSCRIBE: + return MqttFixedHeader.SUBSCRIBE_HEADER; + case SUBACK: + return MqttFixedHeader.SUB_ACK_HEADER; + case UNSUBACK: + return MqttFixedHeader.UNSUB_ACK_HEADER; + case UNSUBSCRIBE: + return MqttFixedHeader.UNSUBSCRIBE_HEADER; + case PUBLISH: + return new MqttFixedHeader(messageType, dup, MqttQoS.valueOf(qosLevel), retain); + case PUBACK: + return MqttFixedHeader.PUB_ACK_HEADER; + case PUBREC: + return MqttFixedHeader.PUB_REC_HEADER; + case PUBREL: + return MqttFixedHeader.PUB_REL_HEADER; + case PUBCOMP: + return MqttFixedHeader.PUB_COMP_HEADER; + case PINGREQ: + return MqttFixedHeader.PING_REQ_HEADER; + case PINGRESP: + return MqttFixedHeader.PING_RESP_HEADER; + case DISCONNECT: + return MqttFixedHeader.DISCONNECT_HEADER; + default: + throw new IllegalArgumentException("unknown message type: " + messageType); + } + } + public static MqttMessage newMessage(MqttFixedHeader mqttFixedHeader) { switch (mqttFixedHeader.getMessageType()) { case CONNECT: diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttProtocol.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttProtocol.java index 7ccc5c87..2ac415e2 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttProtocol.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttProtocol.java @@ -3,9 +3,7 @@ package org.smartboot.mqtt.common.protocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smartboot.mqtt.common.enums.MqttMessageType; -import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.enums.MqttVersion; -import org.smartboot.mqtt.common.message.MqttCodecUtil; import org.smartboot.mqtt.common.message.MqttFixedHeader; import org.smartboot.mqtt.common.message.MqttMessage; import org.smartboot.mqtt.common.util.ValidateUtils; @@ -83,27 +81,19 @@ public class MqttProtocol implements Protocol { } buffer.mark(); - MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(messageType, dupFlag, MqttQoS.valueOf(qosLevel), retain, remainingLength); - MqttCodecUtil.resetUnusedFields(mqttFixedHeader); -// switch (mqttFixedHeader.getMessageType()) { -// case PUBREL: -// case SUBSCRIBE: -// case UNSUBSCRIBE: -// if (mqttFixedHeader.getQosLevel() != MqttQoS.AT_LEAST_ONCE) { -// throw new DecoderException(mqttFixedHeader.getMessageType().name() + " message must have QoS 1"); -// } -// } - unit.mqttMessage = MqttMessageFactory.newMessage(mqttFixedHeader); - //非MqttConnectMessage对象为null, - if (unit.mqttMessage.getVersion() == null) { - unit.mqttMessage.setVersion(attachment.get(MQTT_VERSION_ATTACH_KEY)); - } + MqttFixedHeader mqttFixedHeader = MqttMessageFactory.newMqttFixedHeader(messageType, dupFlag, qosLevel, retain); + unit.mqttMessage = MqttMessageFactory.newMessage(mqttFixedHeader); + unit.mqttMessage.setRemainingLength(remainingLength); + //非MqttConnectMessage对象为null, + if (unit.mqttMessage.getVersion() == null) { + unit.mqttMessage.setVersion(attachment.get(MQTT_VERSION_ATTACH_KEY)); + } - unit.state = READ_VARIABLE_HEADER; + unit.state = READ_VARIABLE_HEADER; } case READ_VARIABLE_HEADER: { - int remainingLength = unit.mqttMessage.getFixedHeader().remainingLength(); + int remainingLength = unit.mqttMessage.getRemainingLength(); if (remainingLength > maxBytesInMessage) { throw new DecoderException("too large message: " + remainingLength + " bytes"); } -- Gitee From 97b724259556ec4c79580cfa5bf97c463018464c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 10 Mar 2023 21:11:57 +0800 Subject: [PATCH 09/29] =?UTF-8?q?=E5=86=85=E5=AD=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/common/message/MqttFixedHeader.java | 7 +++++++ .../mqtt/common/protocol/MqttMessageFactory.java | 14 +++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java index a52b741d..4e152214 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttFixedHeader.java @@ -33,6 +33,13 @@ public class MqttFixedHeader { public static final MqttFixedHeader PING_REQ_HEADER = new MqttFixedHeader(MqttMessageType.PINGREQ, MqttQoS.AT_MOST_ONCE); public static final MqttFixedHeader PING_RESP_HEADER = new MqttFixedHeader(MqttMessageType.PINGRESP, MqttQoS.AT_MOST_ONCE); public static final MqttFixedHeader DISCONNECT_HEADER = new MqttFixedHeader(MqttMessageType.DISCONNECT, MqttQoS.AT_MOST_ONCE); + + public static final MqttFixedHeader PUB_QOS0_HEADER = new MqttFixedHeader(MqttMessageType.PUBLISH, false, MqttQoS.AT_MOST_ONCE, false); + public static final MqttFixedHeader PUB_QOS1_HEADER = new MqttFixedHeader(MqttMessageType.PUBLISH, false, MqttQoS.AT_LEAST_ONCE, false); + public static final MqttFixedHeader PUB_QOS2_HEADER = new MqttFixedHeader(MqttMessageType.PUBLISH, false, MqttQoS.EXACTLY_ONCE, false); + + public static final MqttFixedHeader PUB_FAILURE_HEADER = new MqttFixedHeader(MqttMessageType.PUBLISH, false, MqttQoS.FAILURE, false); + private final MqttMessageType messageType; /** * 重发标志 diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java index d486f672..0d2e9c24 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/protocol/MqttMessageFactory.java @@ -39,7 +39,19 @@ final class MqttMessageFactory { case UNSUBSCRIBE: return MqttFixedHeader.UNSUBSCRIBE_HEADER; case PUBLISH: - return new MqttFixedHeader(messageType, dup, MqttQoS.valueOf(qosLevel), retain); + if (dup || retain) { + return new MqttFixedHeader(messageType, dup, MqttQoS.valueOf(qosLevel), retain); + } + switch (qosLevel) { + case 0: + return MqttFixedHeader.PUB_QOS0_HEADER; + case 1: + return MqttFixedHeader.PUB_QOS1_HEADER; + case 2: + return MqttFixedHeader.PUB_QOS2_HEADER; + default: + return MqttFixedHeader.PUB_FAILURE_HEADER; + } case PUBACK: return MqttFixedHeader.PUB_ACK_HEADER; case PUBREC: -- Gitee From 548cae6cab4f9082cf60e49a68217f81669ef827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 10 Mar 2023 21:52:54 +0800 Subject: [PATCH 10/29] =?UTF-8?q?=E5=86=85=E5=AD=98=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java | 2 ++ .../java/org/smartboot/mqtt/client/ClientQosPublisher.java | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java index 8bcf6fe6..e8781d34 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java @@ -28,6 +28,7 @@ import org.smartboot.mqtt.common.message.MqttPublishMessage; import org.smartboot.mqtt.common.message.MqttSubscribeMessage; import org.smartboot.mqtt.common.message.MqttUnsubscribeMessage; import org.smartboot.socket.StateMachineEnum; +import org.smartboot.socket.extension.plugins.MonitorPlugin; import org.smartboot.socket.extension.processor.AbstractMessageProcessor; import org.smartboot.socket.transport.AioSession; import org.smartboot.socket.util.Attachment; @@ -69,6 +70,7 @@ public class MqttBrokerMessageProcessor extends AbstractMessageProcessor(5)); } @Override diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java index 9feb5a13..b254b6a1 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java @@ -1,5 +1,7 @@ package org.smartboot.mqtt.client; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.smartboot.mqtt.common.AbstractSession; import org.smartboot.mqtt.common.AsyncTask; import org.smartboot.mqtt.common.QosPublisher; @@ -14,6 +16,7 @@ import java.util.concurrent.TimeUnit; * @version V1.0 , 2022/4/25 */ public class ClientQosPublisher extends QosPublisher { + private static final Logger LOGGER = LoggerFactory.getLogger(ClientQosPublisher.class); @Override protected void retry(CompletableFuture future, AbstractSession session, MqttMessage mqttMessage) { @@ -22,6 +25,7 @@ public class ClientQosPublisher extends QosPublisher { @Override public void execute() { if (!future.isDone()) { + LOGGER.info("retry..."); session.write(mqttMessage); } } -- Gitee From 7dd33fed79ff2293dcd0eb6b240f5fc6d77cb00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 10 Mar 2023 22:18:51 +0800 Subject: [PATCH 11/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/common/message/MqttCodecUtil.java | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java index 05746dc1..5bf8d6a1 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/MqttCodecUtil.java @@ -2,7 +2,6 @@ package org.smartboot.mqtt.common.message; import org.smartboot.mqtt.common.MqttWriter; -import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.exception.MqttException; import org.smartboot.socket.util.BufferUtils; import org.smartboot.socket.util.DecoderException; @@ -20,45 +19,6 @@ public final class MqttCodecUtil { private MqttCodecUtil() { } - public static MqttFixedHeader resetUnusedFields(MqttFixedHeader mqttFixedHeader) { - switch (mqttFixedHeader.getMessageType()) { - case CONNECT: - case CONNACK: - case PUBACK: - case PUBREC: - case PUBCOMP: - case SUBACK: - case UNSUBACK: - case PINGREQ: - case PINGRESP: - case DISCONNECT: - if (mqttFixedHeader.isDup() || - mqttFixedHeader.getQosLevel() != MqttQoS.AT_MOST_ONCE || - mqttFixedHeader.isRetain()) { - return new MqttFixedHeader( - mqttFixedHeader.getMessageType(), - false, - MqttQoS.AT_MOST_ONCE, - false); - } - return mqttFixedHeader; - case PUBREL: - case SUBSCRIBE: - case UNSUBSCRIBE: - if (mqttFixedHeader.isRetain()) { - return new MqttFixedHeader( - mqttFixedHeader.getMessageType(), - mqttFixedHeader.isDup(), - mqttFixedHeader.getQosLevel(), - false); - } - return mqttFixedHeader; - default: - return mqttFixedHeader; - } - } - - /** * 解码变长字节整数,规范1.5.5 */ -- Gitee From ab4f0b103f1589c63e814b22a22a3a297957ed7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 10 Mar 2023 22:52:48 +0800 Subject: [PATCH 12/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eventbus/ConnectIdleTimeMonitorSubscriber.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/eventbus/ConnectIdleTimeMonitorSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/eventbus/ConnectIdleTimeMonitorSubscriber.java index 1ebfdb53..2542c27f 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/eventbus/ConnectIdleTimeMonitorSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/eventbus/ConnectIdleTimeMonitorSubscriber.java @@ -9,7 +9,6 @@ import org.smartboot.mqtt.common.eventbus.EventBusSubscriber; import org.smartboot.mqtt.common.eventbus.EventType; import org.smartboot.socket.util.QuickTimerTask; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** @@ -22,21 +21,17 @@ public class ConnectIdleTimeMonitorSubscriber implements EventBusSubscriber map = new ConcurrentHashMap<>(); - public ConnectIdleTimeMonitorSubscriber(BrokerContext context) { this.context = context; } @Override public void subscribe(EventType eventType, MqttSession session) { - map.put(session, session); - context.getEventBus().subscribe(ServerEventType.CONNECT, (eventType1, object) -> map.remove(object.getSession())); QuickTimerTask.SCHEDULED_EXECUTOR_SERVICE.schedule(new AsyncTask() { @Override public void execute() { - if (map.remove(session) != null) { - LOGGER.debug("长时间未收到客户端:{} 的Connect消息,连接断开!", session.getClientId()); + if (!session.isAuthorized()) { + LOGGER.info("长时间未收到客户端:{} 的Connect消息,连接断开!", session.getClientId()); session.disconnect(); } } -- Gitee From a4a3637f9ad7c2eae6741d8d20a08578f3a7ee3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 11 Mar 2023 10:31:05 +0800 Subject: [PATCH 13/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/smartboot/mqtt/common/QosPublisher.java | 1 - 1 file changed, 1 deletion(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java index 47a0f8fe..b5a077b2 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java @@ -30,7 +30,6 @@ public abstract class QosPublisher { ValidateUtils.isTrue(message.getFixedHeader().getMessageType() == MqttMessageType.PUBACK, "invalid message type"); future.complete(true); session.responseConsumers.remove(cacheKey); - LOGGER.info("Qos1消息发送成功..."); consumer.accept(publishMessage.getVariableHeader().getPacketId()); })); session.write(publishMessage, autoFlush); -- Gitee From 751579d542e4c739944ff70986942ba21b340875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 11 Mar 2023 11:08:35 +0800 Subject: [PATCH 14/29] =?UTF-8?q?=E5=BC=80=E5=8F=91=200.16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 ++-- smart-mqtt-broker/pom.xml | 2 +- .../main/java/org/smartboot/mqtt/broker/BrokerConfigure.java | 2 +- smart-mqtt-client/pom.xml | 2 +- smart-mqtt-common/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index df998158..dd9ff4f0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,12 @@ org.smartboot.mqtt smart-mqtt smart-mqtt - 0.15 + 0.16 4.0.0 mqtt broker - 0.15 + 0.16 1.5.25 1.1.22 2.6 diff --git a/smart-mqtt-broker/pom.xml b/smart-mqtt-broker/pom.xml index e594976c..6be67884 100644 --- a/smart-mqtt-broker/pom.xml +++ b/smart-mqtt-broker/pom.xml @@ -5,7 +5,7 @@ org.smartboot.mqtt smart-mqtt - 0.15 + 0.16 ../pom.xml 4.0.0 diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerConfigure.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerConfigure.java index 6f0e231c..c06ab594 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerConfigure.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerConfigure.java @@ -28,7 +28,7 @@ public class BrokerConfigure extends ToString { /** * 当前smart-mqtt */ - public static final String VERSION = "v0.15"; + public static final String VERSION = "v0.16"; static final Map SystemEnvironments = new HashMap<>(); diff --git a/smart-mqtt-client/pom.xml b/smart-mqtt-client/pom.xml index 87b498ff..4b2a1983 100644 --- a/smart-mqtt-client/pom.xml +++ b/smart-mqtt-client/pom.xml @@ -5,7 +5,7 @@ smart-mqtt org.smartboot.mqtt - 0.15 + 0.16 ../pom.xml 4.0.0 diff --git a/smart-mqtt-common/pom.xml b/smart-mqtt-common/pom.xml index f0a3e11b..6203e97b 100644 --- a/smart-mqtt-common/pom.xml +++ b/smart-mqtt-common/pom.xml @@ -5,7 +5,7 @@ smart-mqtt org.smartboot.mqtt - 0.15 + 0.16 ../pom.xml 4.0.0 -- Gitee From f0cd1f4a8f3bd829a16d192acafa8327a3ced4fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 11 Mar 2023 12:27:00 +0800 Subject: [PATCH 15/29] =?UTF-8?q?=E5=BC=80=E5=8F=91=200.16?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java index e8781d34..8bcf6fe6 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java @@ -28,7 +28,6 @@ import org.smartboot.mqtt.common.message.MqttPublishMessage; import org.smartboot.mqtt.common.message.MqttSubscribeMessage; import org.smartboot.mqtt.common.message.MqttUnsubscribeMessage; import org.smartboot.socket.StateMachineEnum; -import org.smartboot.socket.extension.plugins.MonitorPlugin; import org.smartboot.socket.extension.processor.AbstractMessageProcessor; import org.smartboot.socket.transport.AioSession; import org.smartboot.socket.util.Attachment; @@ -70,7 +69,6 @@ public class MqttBrokerMessageProcessor extends AbstractMessageProcessor(5)); } @Override -- Gitee From cf545e39ff2c76cff6972ca9476cb9a5bd975819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 11 Mar 2023 13:15:34 +0800 Subject: [PATCH 16/29] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8E=8B=E6=B5=8B?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3543fe0f..718a1af2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ networks: mqtt-network: driver: bridge services: - smart-mqtt: + mqtt-broker: container_name: smart-mqtt hostname: mqtt-broker image: smartboot/smart-mqtt:latest @@ -18,7 +18,7 @@ services: options: max-size: "100m" max-file: "1" -# emqx: +# mqtt-broker: # container_name: emqx # hostname: mqtt-broker # image: emqx/emqx:5.0.3 @@ -36,8 +36,7 @@ services: smart-mqtt-bench: depends_on: -# - emqx - - smart-mqtt + - mqtt-broker image: smartboot/smart-mqtt-bench:latest read_only: true restart: always @@ -51,6 +50,6 @@ services: options: max-size: "100m" max-file: "1" - command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=2000 -Dpublisher=2 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Subscribe -# command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=1000 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Publish +# command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=2000 -Dpublisher=2 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Subscribe + command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=1000 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Publish version: '3.7' \ No newline at end of file -- Gitee From 38b3f5e722d4422103b9e488efaf55e73b0b5a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 11 Mar 2023 14:12:18 +0800 Subject: [PATCH 17/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 5 +++-- .../java/org/smartboot/mqtt/broker/TopicSubscriber.java | 6 +++++- .../main/java/org/smartboot/mqtt/common/InflightQueue.java | 4 ++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 718a1af2..9b886d23 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,7 @@ services: options: max-size: "100m" max-file: "1" + # mqtt-broker: # container_name: emqx # hostname: mqtt-broker @@ -50,6 +51,6 @@ services: options: max-size: "100m" max-file: "1" -# command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=2000 -Dpublisher=2 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Subscribe - command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=1000 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Publish + command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=2000 -Dqos=2 -Dpublisher=2 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Subscribe +# command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=1000 -Dqos=2 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Publish version: '3.7' \ No newline at end of file diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index 8dd931c5..a2783996 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -64,6 +64,9 @@ public class TopicSubscriber { } private long publish0(BrokerContext brokerContext, int depth, long expectConsumerOffset) { + if (mqttSession.getInflightQueue().isFull()) { + return expectConsumerOffset; + } PersistenceProvider persistenceProvider = brokerContext.getProviders().getPersistenceProvider(); int version = topic.getVersion().get(); PersistenceMessage persistenceMessage = persistenceProvider.get(topic.getTopic(), expectConsumerOffset); @@ -74,6 +77,7 @@ public class TopicSubscriber { } if (depth > 16) { mqttSession.flush(); + LOGGER.info("退出递归..."); // System.out.println("退出递归..."); return expectConsumerOffset; } @@ -93,7 +97,7 @@ public class TopicSubscriber { // 飞行队列已满 if (index == -1) { mqttSession.flush(); -// System.out.println("queue is full..." + expectConsumerOffset); + LOGGER.info("queue is full..." + expectConsumerOffset); return expectConsumerOffset; } long start = System.currentTimeMillis(); diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index b374e47c..54d8b12e 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -34,6 +34,10 @@ public class InflightQueue { return index; } + public boolean isFull() { + return count == queue.length; + } + public synchronized long commit(int commitIndex) { if (commitIndex != takeIndex) { //转负数表示以提交 -- Gitee From 96a1d49090c4b1d2e27a70c19a1bd44e006c90b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sun, 12 Mar 2023 18:32:06 +0800 Subject: [PATCH 18/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/broker/TopicSubscriber.java | 27 ++++++++----------- .../smartboot/mqtt/common/InflightQueue.java | 4 --- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index a2783996..dd361987 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -60,26 +60,21 @@ public class TopicSubscriber { } public void batchPublish(BrokerContext brokerContext) { - nextConsumerOffset = publish0(brokerContext, 0, nextConsumerOffset); + publish0(brokerContext, 0); + mqttSession.flush(); } - private long publish0(BrokerContext brokerContext, int depth, long expectConsumerOffset) { - if (mqttSession.getInflightQueue().isFull()) { - return expectConsumerOffset; - } + private void publish0(BrokerContext brokerContext, int depth) { PersistenceProvider persistenceProvider = brokerContext.getProviders().getPersistenceProvider(); int version = topic.getVersion().get(); - PersistenceMessage persistenceMessage = persistenceProvider.get(topic.getTopic(), expectConsumerOffset); + PersistenceMessage persistenceMessage = persistenceProvider.get(topic.getTopic(), nextConsumerOffset); if (persistenceMessage == null) { pushVersion = version; - mqttSession.flush(); - return expectConsumerOffset; + return; } if (depth > 16) { - mqttSession.flush(); - LOGGER.info("退出递归..."); -// System.out.println("退出递归..."); - return expectConsumerOffset; +// LOGGER.info("退出递归..."); + return; } MqttMessageBuilders.PublishBuilder publishBuilder = MqttMessageBuilders.publish().payload(persistenceMessage.getPayload()).qos(mqttQoS).topicName(persistenceMessage.getTopic()); @@ -96,11 +91,11 @@ public class TopicSubscriber { int index = inflightQueue.offer(publishMessage, persistenceMessage.getOffset()); // 飞行队列已满 if (index == -1) { - mqttSession.flush(); - LOGGER.info("queue is full..." + expectConsumerOffset); - return expectConsumerOffset; +// LOGGER.info("queue is full..." + expectConsumerOffset); + return; } long start = System.currentTimeMillis(); + nextConsumerOffset++; mqttSession.publish(publishMessage, packetId -> { //最早发送的消息若收到响应,则更新点位 long offset = inflightQueue.commit(index); @@ -119,7 +114,7 @@ public class TopicSubscriber { } brokerContext.getEventBus().publish(EventType.PUSH_PUBLISH_MESSAGE, mqttSession); //递归处理下一个消息 - return publish0(brokerContext, ++depth, expectConsumerOffset + 1); + publish0(brokerContext, ++depth); } public BrokerTopic getTopic() { diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index 54d8b12e..b374e47c 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -34,10 +34,6 @@ public class InflightQueue { return index; } - public boolean isFull() { - return count == queue.length; - } - public synchronized long commit(int commitIndex) { if (commitIndex != takeIndex) { //转负数表示以提交 -- Gitee From 8bd5029be35d3791881c92a75e17e954d4fa9922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Tue, 14 Mar 2023 18:31:56 +0800 Subject: [PATCH 19/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/broker/BrokerContextImpl.java | 29 +++++++++++++------ .../smartboot/mqtt/broker/BrokerTopic.java | 7 +++++ .../mqtt/broker/TopicSubscriber.java | 27 ++++++----------- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java index d03f3e46..de13ee5c 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java @@ -60,6 +60,7 @@ import java.util.ServiceLoader; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -241,6 +242,8 @@ public class BrokerContextImpl implements BrokerContext { providers.setConnectAuthenticationProvider(new ConfiguredConnectAuthenticationProviderImpl(this)); } + private final TopicSubscriber BREAK = new TopicSubscriber(null, null, null, 0, 0); + private void initPushThread() { if (brokerConfigure.getTopicLimit() <= 0) { brokerConfigure.setTopicLimit(10); @@ -280,14 +283,22 @@ public class BrokerContextImpl implements BrokerContext { } try { //存在待输出消息 - Collection subscribers = brokerTopic.getConsumeOffsets().values(); - subscribers.stream().filter(topicSubscriber -> topicSubscriber.isReady() && topicSubscriber.getPushVersion() != brokerTopic.getVersion().get()).forEach(topicSubscriber -> topicSubscriber.batchPublish(BrokerContextImpl.this)); - brokerTopic.getSemaphore().release(); - for (TopicSubscriber subscriber : subscribers) { - if (subscriber.getPushVersion() != brokerTopic.getVersion().get()) { - notifyPush(brokerTopic); + ConcurrentLinkedQueue subscribers = brokerTopic.getQueue(); + subscribers.offer(BREAK); + TopicSubscriber subscriber = null; + int version = brokerTopic.getVersion().get(); + while ((subscriber = subscribers.poll()) != null) { + if (subscriber == BREAK) { break; } + subscriber.batchPublish(BrokerContextImpl.this); + } + brokerTopic.getSemaphore().release(); + if (version != brokerTopic.getVersion().get() && !subscribers.isEmpty()) { + System.out.println("continue..." + brokerTopic.getTopic()); + notifyPush(brokerTopic); + } else { +// System.out.println("empty...." + brokerTopic.getTopic()); } } catch (Exception e) { LOGGER.error("brokerTopic:{} push message exception", brokerTopic.getTopic(), e); @@ -344,8 +355,8 @@ public class BrokerContextImpl implements BrokerContext { AsyncTask task = this; PersistenceMessage storedMessage = providers.getRetainMessageProvider().get(subscriber.getTopic().getTopic(), subscriber.getRetainConsumerOffset()); if (storedMessage == null || storedMessage.getCreateTime() > subscriber.getLatestSubscribeTime()) { - subscriber.setReady(true); BrokerTopic topic = subscriber.getTopic(); + topic.getQueue().offer(subscriber); notifyPush(topic); //完成retain消息的消费,正式开始监听Topic @@ -381,11 +392,11 @@ public class BrokerContextImpl implements BrokerContext { }); eventBus.subscribe(ServerEventType.SUBSCRIBE_REFRESH_TOPIC, (eventType, subscriber) -> { LOGGER.info("刷新订阅关系, {} 订阅了topic: {}", subscriber.getTopicFilterToken().getTopicFilter(), subscriber.getTopic().getTopic()); - subscriber.setReady(true); + subscriber.getTopic().getQueue().offer(subscriber); }); } - private void notifyPush(BrokerTopic topic) { + void notifyPush(BrokerTopic topic) { if (!topic.getSemaphore().tryAcquire()) { return; } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java index 357a7f9f..c127ee45 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerTopic.java @@ -4,6 +4,7 @@ import org.smartboot.mqtt.common.Topic; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; @@ -24,6 +25,8 @@ public class BrokerTopic extends Topic { */ private final Semaphore semaphore = new Semaphore(1); + private final ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); + public BrokerTopic(String topic) { super(topic); } @@ -39,4 +42,8 @@ public class BrokerTopic extends Topic { public Semaphore getSemaphore() { return semaphore; } + + public ConcurrentLinkedQueue getQueue() { + return queue; + } } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index dd361987..75277fba 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -47,9 +47,8 @@ public class TopicSubscriber { private final long latestSubscribeTime = System.currentTimeMillis(); private TopicToken topicFilterToken; - private int pushVersion = -1; - private boolean ready = false; + private boolean inQueue = true; public TopicSubscriber(BrokerTopic topic, MqttSession session, MqttQoS mqttQoS, long nextConsumerOffset, long retainConsumerOffset) { this.topic = topic; @@ -60,20 +59,23 @@ public class TopicSubscriber { } public void batchPublish(BrokerContext brokerContext) { + inQueue = false; publish0(brokerContext, 0); mqttSession.flush(); } - private void publish0(BrokerContext brokerContext, int depth) { + private synchronized void publish0(BrokerContext brokerContext, int depth) { PersistenceProvider persistenceProvider = brokerContext.getProviders().getPersistenceProvider(); - int version = topic.getVersion().get(); PersistenceMessage persistenceMessage = persistenceProvider.get(topic.getTopic(), nextConsumerOffset); if (persistenceMessage == null) { - pushVersion = version; + if (!inQueue) { + inQueue = true; + topic.getQueue().offer(this); + } return; } if (depth > 16) { -// LOGGER.info("退出递归..."); + LOGGER.info("退出递归..."); return; } @@ -107,6 +109,7 @@ public class TopicSubscriber { setRetainConsumerOffset(getRetainConsumerOffset() + 1); } commitRetainConsumerTimestamp(persistenceMessage.getCreateTime()); + batchPublish(brokerContext); }, false); long cost = System.currentTimeMillis() - start; if (cost > 100) { @@ -161,16 +164,4 @@ public class TopicSubscriber { public void setTopicFilterToken(TopicToken topicFilterToken) { this.topicFilterToken = topicFilterToken; } - - public boolean isReady() { - return ready; - } - - public void setReady(boolean ready) { - this.ready = ready; - } - - public int getPushVersion() { - return pushVersion; - } } -- Gitee From b075820b82d8be5c77558f212d7c33be805bb1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Tue, 14 Mar 2023 20:41:01 +0800 Subject: [PATCH 20/29] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../smartboot/mqtt/broker/BrokerContextImpl.java | 11 ++++------- .../org/smartboot/mqtt/broker/TopicSubscriber.java | 14 +++++++++----- .../org/smartboot/mqtt/common/InflightQueue.java | 4 ++++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java index de13ee5c..094d4f41 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java @@ -287,18 +287,15 @@ public class BrokerContextImpl implements BrokerContext { subscribers.offer(BREAK); TopicSubscriber subscriber = null; int version = brokerTopic.getVersion().get(); - while ((subscriber = subscribers.poll()) != null) { - if (subscriber == BREAK) { - break; - } + while ((subscriber = subscribers.poll()) != BREAK) { +// if (subscriber == BREAK) { +// break; +// } subscriber.batchPublish(BrokerContextImpl.this); } brokerTopic.getSemaphore().release(); if (version != brokerTopic.getVersion().get() && !subscribers.isEmpty()) { - System.out.println("continue..." + brokerTopic.getTopic()); notifyPush(brokerTopic); - } else { -// System.out.println("empty...." + brokerTopic.getTopic()); } } catch (Exception e) { LOGGER.error("brokerTopic:{} push message exception", brokerTopic.getTopic(), e); diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index 75277fba..a8f206fa 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -13,6 +13,8 @@ import org.smartboot.mqtt.common.eventbus.EventType; import org.smartboot.mqtt.common.message.MqttPublishMessage; import org.smartboot.mqtt.common.message.variable.properties.PublishProperties; +import java.util.concurrent.Semaphore; + /** * Topic订阅者 * @@ -48,7 +50,7 @@ public class TopicSubscriber { private TopicToken topicFilterToken; - private boolean inQueue = true; + private final Semaphore semaphore = new Semaphore(0); public TopicSubscriber(BrokerTopic topic, MqttSession session, MqttQoS mqttQoS, long nextConsumerOffset, long retainConsumerOffset) { this.topic = topic; @@ -59,7 +61,7 @@ public class TopicSubscriber { } public void batchPublish(BrokerContext brokerContext) { - inQueue = false; + semaphore.release(); publish0(brokerContext, 0); mqttSession.flush(); } @@ -68,8 +70,7 @@ public class TopicSubscriber { PersistenceProvider persistenceProvider = brokerContext.getProviders().getPersistenceProvider(); PersistenceMessage persistenceMessage = persistenceProvider.get(topic.getTopic(), nextConsumerOffset); if (persistenceMessage == null) { - if (!inQueue) { - inQueue = true; + if (semaphore.tryAcquire()) { topic.getQueue().offer(this); } return; @@ -109,7 +110,10 @@ public class TopicSubscriber { setRetainConsumerOffset(getRetainConsumerOffset() + 1); } commitRetainConsumerTimestamp(persistenceMessage.getCreateTime()); - batchPublish(brokerContext); + if (inflightQueue.getCount() == 0) { + publish0(brokerContext, 0); + mqttSession.flush(); + } }, false); long cost = System.currentTimeMillis() - start; if (cost > 100) { diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index b374e47c..32ecd628 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -58,4 +58,8 @@ public class InflightQueue { } return offset; } + + public int getCount() { + return count; + } } \ No newline at end of file -- Gitee From 1070220d2a11c15999a64ad0eb0d855098ccc9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Wed, 15 Mar 2023 22:22:57 +0800 Subject: [PATCH 21/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/broker/BrokerContextImpl.java | 14 +-- .../mqtt/broker/BrokerQosPublisher.java | 41 -------- .../broker/MqttBrokerMessageProcessor.java | 8 +- .../smartboot/mqtt/broker/MqttSession.java | 6 +- .../mqtt/broker/TopicSubscriber.java | 33 +++---- .../broker/processor/ConnectProcessor.java | 8 +- .../broker/processor/MqttAckProcessor.java | 5 +- .../broker/processor/PublishProcessor.java | 39 ++++---- .../mqtt/client/ClientQosPublisher.java | 34 ------- .../org/smartboot/mqtt/client/MqttClient.java | 99 +++++++++---------- .../client/processor/MqttAckProcessor.java | 5 +- .../client/processor/PublishProcessor.java | 26 ++--- .../mqtt/common/AbstractSession.java | 60 +++-------- .../org/smartboot/mqtt/common/AckMessage.java | 58 +++++++---- .../smartboot/mqtt/common/InflightQueue.java | 84 ++++++++++++---- .../smartboot/mqtt/common/QosPublisher.java | 74 -------------- .../variable/MqttPacketIdVariableHeader.java | 6 +- 17 files changed, 238 insertions(+), 362 deletions(-) delete mode 100644 smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java delete mode 100644 smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java delete mode 100644 smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java index 094d4f41..717747cb 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java @@ -20,7 +20,6 @@ import org.smartboot.mqtt.common.AsyncTask; import org.smartboot.mqtt.common.InflightQueue; import org.smartboot.mqtt.common.MqttMessageBuilders; import org.smartboot.mqtt.common.enums.MqttMetricEnum; -import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.enums.MqttVersion; import org.smartboot.mqtt.common.eventbus.EventBus; import org.smartboot.mqtt.common.eventbus.EventBusImpl; @@ -363,18 +362,13 @@ public class BrokerContextImpl implements BrokerContext { MqttSession session = subscriber.getMqttSession(); MqttMessageBuilders.PublishBuilder publishBuilder = MqttMessageBuilders.publish().payload(storedMessage.getPayload()).qos(subscriber.getMqttQoS()).topicName(storedMessage.getTopic()); - if (subscriber.getMqttQoS() == MqttQoS.AT_LEAST_ONCE || subscriber.getMqttQoS() == MqttQoS.EXACTLY_ONCE) { - publishBuilder.packetId(session.newPacketId()); - } if (session.getMqttVersion() == MqttVersion.MQTT_5) { publishBuilder.publishProperties(new PublishProperties()); } - MqttPublishMessage publishMessage = publishBuilder.build(); InflightQueue inflightQueue = session.getInflightQueue(); - int index = inflightQueue.offer(publishMessage, storedMessage.getOffset()); - session.publish(publishMessage, packetId -> { - LOGGER.info("publish retain to client:{} success ,message:{} ", session.getClientId(), publishMessage); - long offset = inflightQueue.commit(index); + inflightQueue.offer(publishBuilder, integer -> { + LOGGER.info("publish retain to client:{} success ", session.getClientId()); + long offset = inflightQueue.commit(integer); if (offset != -1) { subscriber.setRetainConsumerOffset(offset + 1); retainPushThreadPool.execute(task); @@ -382,7 +376,7 @@ public class BrokerContextImpl implements BrokerContext { LOGGER.error("error..."); } - }); + }, storedMessage.getOffset()); } }); } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java deleted file mode 100644 index 99d73ad0..00000000 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerQosPublisher.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.smartboot.mqtt.broker; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.smartboot.mqtt.common.AbstractSession; -import org.smartboot.mqtt.common.AsyncTask; -import org.smartboot.mqtt.common.QosPublisher; -import org.smartboot.mqtt.common.message.MqttMessage; -import org.smartboot.socket.util.QuickTimerTask; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -/** - * @author 三刀(zhengjunweimail@163.com) - * @version V1.0 , 2022/4/25 - */ -public class BrokerQosPublisher extends QosPublisher { - private static final Logger LOGGER = LoggerFactory.getLogger(BrokerQosPublisher.class); - private final BrokerContext mqttContext; - - public BrokerQosPublisher(BrokerContext mqttContext) { - this.mqttContext = mqttContext; - } - - @Override - protected void retry(CompletableFuture future, AbstractSession session, MqttMessage mqttMessage) { - //注册重试 - QuickTimerTask.SCHEDULED_EXECUTOR_SERVICE.schedule(new AsyncTask() { - @Override - public void execute() { - if (!future.isDone()) { - // 如果客户端发生过断链,则 mqttSession!=session - LOGGER.info("retry..."); - MqttSession mqttSession = mqttContext.getSession(session.getClientId()); - mqttSession.write(mqttMessage); - } - } - }, 1, TimeUnit.SECONDS); - } -} diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java index 8bcf6fe6..048732d4 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/MqttBrokerMessageProcessor.java @@ -11,7 +11,6 @@ import org.smartboot.mqtt.broker.processor.PublishProcessor; import org.smartboot.mqtt.broker.processor.SubscribeProcessor; import org.smartboot.mqtt.broker.processor.UnSubscribeProcessor; import org.smartboot.mqtt.common.DefaultMqttWriter; -import org.smartboot.mqtt.common.QosPublisher; import org.smartboot.mqtt.common.enums.MqttMetricEnum; import org.smartboot.mqtt.common.eventbus.EventObject; import org.smartboot.mqtt.common.eventbus.EventType; @@ -51,7 +50,6 @@ public class MqttBrokerMessageProcessor extends AbstractMessageProcessor onlineSessions = new ConcurrentHashMap<>(); private final Map, MqttProcessor> processorMap = new HashMap<>(); - private final QosPublisher qosPublisher; { processorMap.put(MqttPingReqMessage.class, new PingReqProcessor()); @@ -68,7 +66,6 @@ public class MqttBrokerMessageProcessor extends AbstractMessageProcessor sessionState.getSubscribers().put(topicSubscriber.getTopicFilterToken().getTopicFilter(), topicSubscriber.getMqttQoS())); mqttContext.getProviders().getSessionStateProvider().store(clientId, sessionState); } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index a8f206fa..526a2f12 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -10,7 +10,6 @@ import org.smartboot.mqtt.common.TopicToken; import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.enums.MqttVersion; import org.smartboot.mqtt.common.eventbus.EventType; -import org.smartboot.mqtt.common.message.MqttPublishMessage; import org.smartboot.mqtt.common.message.variable.properties.PublishProperties; import java.util.concurrent.Semaphore; @@ -81,27 +80,17 @@ public class TopicSubscriber { } MqttMessageBuilders.PublishBuilder publishBuilder = MqttMessageBuilders.publish().payload(persistenceMessage.getPayload()).qos(mqttQoS).topicName(persistenceMessage.getTopic()); - if (mqttQoS == MqttQoS.AT_LEAST_ONCE || mqttQoS == MqttQoS.EXACTLY_ONCE) { - publishBuilder.packetId(mqttSession.newPacketId()); - } if (mqttSession.getMqttVersion() == MqttVersion.MQTT_5) { publishBuilder.publishProperties(new PublishProperties()); } - MqttPublishMessage publishMessage = publishBuilder.build(); - InflightQueue inflightQueue = mqttSession.getInflightQueue(); - int index = inflightQueue.offer(publishMessage, persistenceMessage.getOffset()); - // 飞行队列已满 - if (index == -1) { -// LOGGER.info("queue is full..." + expectConsumerOffset); - return; - } - long start = System.currentTimeMillis(); - nextConsumerOffset++; - mqttSession.publish(publishMessage, packetId -> { + int index = inflightQueue.offer(publishBuilder, packetId -> { + if (mqttQoS == MqttQoS.AT_MOST_ONCE) { + nextConsumerOffset++; + } //最早发送的消息若收到响应,则更新点位 - long offset = inflightQueue.commit(index); + long offset = inflightQueue.commit(packetId); if (offset == -1) { return; } @@ -114,7 +103,17 @@ public class TopicSubscriber { publish0(brokerContext, 0); mqttSession.flush(); } - }, false); + }, persistenceMessage.getOffset()); + // 飞行队列已满 + if (index == -1) { +// LOGGER.info("queue is full..." + expectConsumerOffset); + return; + } + long start = System.currentTimeMillis(); + if (mqttQoS != MqttQoS.AT_MOST_ONCE) { + nextConsumerOffset++; + } + long cost = System.currentTimeMillis() - start; if (cost > 100) { System.out.println("publish busy ,cost: " + cost); diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/ConnectProcessor.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/ConnectProcessor.java index 0160113f..6f57c96e 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/ConnectProcessor.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/ConnectProcessor.java @@ -80,7 +80,7 @@ public class ConnectProcessor implements MqttProcessor { } else { receiveMaximum = context.getBrokerConfigure().getMaxInflight(); } - session.setInflightQueue(new InflightQueue(receiveMaximum)); + session.setInflightQueue(new InflightQueue(session, receiveMaximum)); //如果服务端收到清理会话(CleanSession)标志为 1 的连接,除了将 CONNACK 报文中的返回码设置为 0 之外, // 还必须将 CONNACK 报文中的当前会话设置(Session Present)标志为 0。 @@ -160,15 +160,11 @@ public class ConnectProcessor implements MqttProcessor { SessionStateProvider sessionStateProvider = context.getProviders().getSessionStateProvider(); SessionState sessionState = sessionStateProvider.get(session.getClientId()); if (sessionState != null) { - session.getResponseConsumers().putAll(sessionState.getResponseConsumers()); sessionState.getSubscribers().forEach(session::subscribe); //客户端设置清理会话(CleanSession)标志为 0 重连时,客户端和服务端必须使用原始的报文标识符重发 //任何未确认的 PUBLISH 报文(如果 QoS>0)和 PUBREL 报文 [MQTT-4.4.0-1]。这是唯一要求客户端或 //服务端重发消息的情况。 - session.getResponseConsumers().forEach((key, ackMessage) -> { - session.getResponseConsumers().put(key, ackMessage); - session.write(ackMessage.getOriginalMessage()); - }); + } } } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/MqttAckProcessor.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/MqttAckProcessor.java index 4b17dc2f..ed4b7b17 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/MqttAckProcessor.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/MqttAckProcessor.java @@ -2,14 +2,13 @@ package org.smartboot.mqtt.broker.processor; import org.smartboot.mqtt.broker.BrokerContext; import org.smartboot.mqtt.broker.MqttSession; -import org.smartboot.mqtt.common.message.MqttVariableMessage; -import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; +import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; /** * @author 三刀(zhengjunweimail@163.com) * @version V1.0 , 2022/4/15 */ -public class MqttAckProcessor> extends AuthorizedMqttProcessor { +public class MqttAckProcessor extends AuthorizedMqttProcessor { @Override public void process0(BrokerContext context, MqttSession session, T t) { session.notifyResponse(t); diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java index 2c377803..60aacf54 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java @@ -10,11 +10,12 @@ import org.smartboot.mqtt.broker.eventbus.ServerEventType; import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.enums.MqttReasonCode; import org.smartboot.mqtt.common.enums.MqttVersion; +import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; import org.smartboot.mqtt.common.message.MqttPubAckMessage; import org.smartboot.mqtt.common.message.MqttPubCompMessage; import org.smartboot.mqtt.common.message.MqttPubRecMessage; -import org.smartboot.mqtt.common.message.MqttPubRelMessage; import org.smartboot.mqtt.common.message.MqttPublishMessage; +import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; import org.smartboot.mqtt.common.message.variable.MqttPubQosVariableHeader; import org.smartboot.mqtt.common.message.variable.properties.ReasonProperties; @@ -101,24 +102,28 @@ public class PublishProcessor extends AuthorizedMqttProcessor) message -> { - //发送pubRel消息。 - //todo - MqttPubQosVariableHeader qosVariableHeader; - //todo - byte code = 0; - if (code != 0) { - ReasonProperties properties = new ReasonProperties(); - qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), properties); - qosVariableHeader.setReasonCode(code); - } else { - qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), null); + session.write(pubRecMessage, new Consumer>() { + @Override + public void accept(MqttPacketIdentifierMessage message) { + //发送pubRel消息。 + //todo + MqttPubQosVariableHeader qosVariableHeader; + //todo + byte code = 0; + if (code != 0) { + ReasonProperties properties = new ReasonProperties(); + qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), properties); + qosVariableHeader.setReasonCode(code); + } else { + qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), null); + } + MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); + session.write(pubRelMessage); + // 消息投递至消息总线 + context.getEventBus().publish(ServerEventType.RECEIVE_PUBLISH_MESSAGE, EventObject.newEventObject(session, mqttPublishMessage)); } - MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); - session.write(pubRelMessage); - // 消息投递至消息总线 - context.getEventBus().publish(ServerEventType.RECEIVE_PUBLISH_MESSAGE, EventObject.newEventObject(session, mqttPublishMessage)); }); } } diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java deleted file mode 100644 index b254b6a1..00000000 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/ClientQosPublisher.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.smartboot.mqtt.client; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.smartboot.mqtt.common.AbstractSession; -import org.smartboot.mqtt.common.AsyncTask; -import org.smartboot.mqtt.common.QosPublisher; -import org.smartboot.mqtt.common.message.MqttMessage; -import org.smartboot.socket.util.QuickTimerTask; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -/** - * @author 三刀(zhengjunweimail@163.com) - * @version V1.0 , 2022/4/25 - */ -public class ClientQosPublisher extends QosPublisher { - private static final Logger LOGGER = LoggerFactory.getLogger(ClientQosPublisher.class); - - @Override - protected void retry(CompletableFuture future, AbstractSession session, MqttMessage mqttMessage) { - //注册重试 - QuickTimerTask.SCHEDULED_EXECUTOR_SERVICE.schedule(new AsyncTask() { - @Override - public void execute() { - if (!future.isDone()) { - LOGGER.info("retry..."); - session.write(mqttMessage); - } - } - }, 1, TimeUnit.SECONDS); - } -} diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java index 669c3568..f08eea8c 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java @@ -4,7 +4,6 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smartboot.mqtt.common.AbstractSession; -import org.smartboot.mqtt.common.AckMessage; import org.smartboot.mqtt.common.DefaultMqttWriter; import org.smartboot.mqtt.common.InflightQueue; import org.smartboot.mqtt.common.MqttMessageBuilders; @@ -18,6 +17,7 @@ import org.smartboot.mqtt.common.message.MqttConnAckMessage; import org.smartboot.mqtt.common.message.MqttConnectMessage; import org.smartboot.mqtt.common.message.MqttDisconnectMessage; import org.smartboot.mqtt.common.message.MqttMessage; +import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; import org.smartboot.mqtt.common.message.MqttPingReqMessage; import org.smartboot.mqtt.common.message.MqttPingRespMessage; import org.smartboot.mqtt.common.message.MqttPublishMessage; @@ -29,6 +29,7 @@ import org.smartboot.mqtt.common.message.MqttUnsubscribeMessage; import org.smartboot.mqtt.common.message.payload.MqttConnectPayload; import org.smartboot.mqtt.common.message.payload.WillMessage; import org.smartboot.mqtt.common.message.variable.MqttConnectVariableHeader; +import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; import org.smartboot.mqtt.common.message.variable.properties.ConnectProperties; import org.smartboot.mqtt.common.message.variable.properties.PublishProperties; import org.smartboot.mqtt.common.message.variable.properties.ReasonProperties; @@ -95,7 +96,7 @@ public class MqttClient extends AbstractSession { } public MqttClient(String host, int port, String clientId, MqttVersion mqttVersion) { - super(new ClientQosPublisher(), new EventBusImpl(EventType.types())); + super(new EventBusImpl(EventType.types())); clientConfigure.setHost(host); clientConfigure.setPort(port); clientConfigure.setMqttVersion(mqttVersion); @@ -154,7 +155,7 @@ public class MqttClient extends AbstractSession { //连接成功,注册订阅消息 if (mqttConnAckMessage.getVariableHeader().connectReturnCode() == MqttConnectReturnCode.CONNECTION_ACCEPTED) { - setInflightQueue(new InflightQueue(16)); + setInflightQueue(new InflightQueue(this, 16)); connected = true; Runnable runnable; while ((runnable = registeredTasks.poll()) != null) { @@ -169,7 +170,7 @@ public class MqttClient extends AbstractSession { //任何未确认的 PUBLISH 报文(如果 QoS>0)和 PUBREL 报文 [MQTT-4.4.0-1]。这是唯一要求客户端或 //服务端重发消息的情况。 if (!clientConfigure.isCleanSession()) { - responseConsumers.values().forEach(ackMessage -> write(ackMessage.getOriginalMessage())); + //todo } consumer.accept(mqttConnAckMessage); connected = true; @@ -282,13 +283,16 @@ public class MqttClient extends AbstractSession { } MqttUnsubscribeMessage unsubscribedMessage = unsubscribeBuilder.build(properties); // wait ack message. - responseConsumers.put(unsubscribedMessage.getVariableHeader().getPacketId(), new AckMessage(unsubscribedMessage, mqttMessage -> { - ValidateUtils.isTrue(mqttMessage instanceof MqttUnsubAckMessage, "uncorrected message type."); - for (String unsubscribedTopic : unsubscribedTopics) { - subscribes.remove(unsubscribedTopic); - wildcardsToken.removeIf(topicToken -> StringUtils.equals(unsubscribedTopic, topicToken.getTopicFilter())); + responseConsumers.put(unsubscribedMessage.getVariableHeader().getPacketId(), new Consumer>() { + @Override + public void accept(MqttPacketIdentifierMessage message) { + ValidateUtils.isTrue(message instanceof MqttUnsubAckMessage, "uncorrected message type."); + for (String unsubscribedTopic : unsubscribedTopics) { + subscribes.remove(unsubscribedTopic); + wildcardsToken.removeIf(topicToken -> StringUtils.equals(unsubscribedTopic, topicToken.getTopicFilter())); + } } - })); + }); write(unsubscribedMessage); } @@ -326,26 +330,30 @@ public class MqttClient extends AbstractSession { } MqttSubscribeMessage subscribeMessage = subscribeBuilder.build(); - responseConsumers.put(subscribeMessage.getVariableHeader().getPacketId(), new AckMessage(subscribeMessage, mqttMessage -> { - List qosValues = ((MqttSubAckMessage) mqttMessage).getPayload().grantedQoSLevels(); - ValidateUtils.isTrue(qosValues.size() == qos.length, "invalid response"); - int i = 0; - for (MqttTopicSubscription subscription : subscribeMessage.getPayload().getTopicSubscriptions()) { - MqttQoS minQos = MqttQoS.valueOf(Math.min(subscription.getQualityOfService().value(), qosValues.get(i++))); - clientConfigure.getTopicListener().subscribe(subscription.getTopicFilter(), subscription.getQualityOfService() == MqttQoS.FAILURE ? MqttQoS.FAILURE : minQos); - if (subscription.getQualityOfService() != MqttQoS.FAILURE) { - subscribes.put(subscription.getTopicFilter(), new Subscribe(subscription.getTopicFilter(), minQos, consumer)); - //缓存统配匹配的topic - TopicToken topicToken = new TopicToken(subscription.getTopicFilter()); - if (topicToken.isWildcards()) { - wildcardsToken.add(topicToken); + responseConsumers.put(subscribeMessage.getVariableHeader().getPacketId(), new Consumer>() { + @Override + public void accept(MqttPacketIdentifierMessage message) { + List qosValues = ((MqttSubAckMessage) message).getPayload().grantedQoSLevels(); + ValidateUtils.isTrue(qosValues.size() == qos.length, "invalid response"); + ValidateUtils.isTrue(qosValues.size() == qos.length, "invalid response"); + int i = 0; + for (MqttTopicSubscription subscription : subscribeMessage.getPayload().getTopicSubscriptions()) { + MqttQoS minQos = MqttQoS.valueOf(Math.min(subscription.getQualityOfService().value(), qosValues.get(i++))); + clientConfigure.getTopicListener().subscribe(subscription.getTopicFilter(), subscription.getQualityOfService() == MqttQoS.FAILURE ? MqttQoS.FAILURE : minQos); + if (subscription.getQualityOfService() != MqttQoS.FAILURE) { + subscribes.put(subscription.getTopicFilter(), new Subscribe(subscription.getTopicFilter(), minQos, consumer)); + //缓存统配匹配的topic + TopicToken topicToken = new TopicToken(subscription.getTopicFilter()); + if (topicToken.isWildcards()) { + wildcardsToken.add(topicToken); + } + } else { + LOGGER.error("subscribe topic:{} fail", subscription.getTopicFilter()); } - } else { - LOGGER.error("subscribe topic:{} fail", subscription.getTopicFilter()); + subAckConsumer.accept(MqttClient.this, minQos); } - subAckConsumer.accept(this, minQos); } - })); + }); write(subscribeMessage); } @@ -373,46 +381,37 @@ public class MqttClient extends AbstractSession { public void publish(String topic, MqttQoS qos, byte[] payload, boolean retain, Consumer consumer) { MqttMessageBuilders.PublishBuilder publishBuilder = MqttMessageBuilders.publish().topicName(topic).qos(qos).payload(payload).retained(retain); - if (qos.value() > 0) { - int packetId = newPacketId(); - publishBuilder.packetId(packetId); - } //todo if (getMqttVersion() == MqttVersion.MQTT_5) { publishBuilder.publishProperties(new PublishProperties()); } - MqttPublishMessage message = publishBuilder.build(); if (connected) { - publish(message, consumer); + publish(publishBuilder, consumer); } else { - registeredTasks.offer(() -> publish(message, consumer)); + registeredTasks.offer(() -> publish(publishBuilder, consumer)); } } - @Override - public synchronized void publish(MqttPublishMessage message, Consumer consumer) { + private synchronized void publish(MqttMessageBuilders.PublishBuilder publishBuilder, Consumer consumer) { InflightQueue inflightQueue = getInflightQueue(); - int index = inflightQueue.offer(message, 1); - if (index == -1) { - try { - wait(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - publish(message, consumer); - return; - } - super.publish(message, packetId -> { + int index = inflightQueue.offer(publishBuilder, packetId -> { consumer.accept(packetId); //最早发送的消息若收到响应,则更新点位 - long offset = inflightQueue.commit(index); + long offset = inflightQueue.commit(packetId); if (offset != -1) { synchronized (MqttClient.this) { MqttClient.this.notifyAll(); } } - - }, true); + }, 1); + if (index == -1) { + try { + wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + publish(publishBuilder, consumer); + } } public MqttClientConfigure getClientConfigure() { diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/MqttAckProcessor.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/MqttAckProcessor.java index 44d8778e..e7bef87c 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/MqttAckProcessor.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/MqttAckProcessor.java @@ -1,14 +1,13 @@ package org.smartboot.mqtt.client.processor; import org.smartboot.mqtt.client.MqttClient; -import org.smartboot.mqtt.common.message.MqttVariableMessage; -import org.smartboot.mqtt.common.message.variable.MqttPubQosVariableHeader; +import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; /** * @author 三刀(zhengjunweimail@163.com) * @version V1.0 , 2022/4/7 */ -public class MqttAckProcessor> implements MqttProcessor { +public class MqttAckProcessor implements MqttProcessor { @Override public void process(MqttClient mqttClient, T message) { mqttClient.notifyResponse(message); diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java index f3338c4b..80625187 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java @@ -7,11 +7,12 @@ import org.smartboot.mqtt.client.Subscribe; import org.smartboot.mqtt.common.TopicToken; import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.enums.MqttVersion; +import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; import org.smartboot.mqtt.common.message.MqttPubAckMessage; import org.smartboot.mqtt.common.message.MqttPubCompMessage; import org.smartboot.mqtt.common.message.MqttPubRecMessage; -import org.smartboot.mqtt.common.message.MqttPubRelMessage; import org.smartboot.mqtt.common.message.MqttPublishMessage; +import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; import org.smartboot.mqtt.common.message.variable.MqttPubQosVariableHeader; import org.smartboot.mqtt.common.message.variable.MqttPublishVariableHeader; import org.smartboot.mqtt.common.message.variable.properties.ReasonProperties; @@ -95,17 +96,20 @@ public class PublishProcessor implements MqttProcessor { MqttPubQosVariableHeader variableHeader = new MqttPubQosVariableHeader(messageId, properties); MqttPubRecMessage pubRecMessage = new MqttPubRecMessage(variableHeader); - session.write(pubRecMessage, (Consumer) message -> { - //todo - ReasonProperties reasonProperties = null; - if (mqttPublishMessage.getVersion() == MqttVersion.MQTT_5) { - reasonProperties = new ReasonProperties(); - } - MqttPubQosVariableHeader qosVariableHeader = new MqttPubQosVariableHeader(message.getVariableHeader().getPacketId(), reasonProperties); - MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); - session.write(pubRelMessage); + session.write(pubRecMessage, new Consumer>() { + @Override + public void accept(MqttPacketIdentifierMessage message) { + //todo + ReasonProperties reasonProperties = null; + if (mqttPublishMessage.getVersion() == MqttVersion.MQTT_5) { + reasonProperties = new ReasonProperties(); + } + MqttPubQosVariableHeader qosVariableHeader = new MqttPubQosVariableHeader(message.getVariableHeader().getPacketId(), reasonProperties); + MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); + session.write(pubRelMessage); - processPublishMessage(mqttPublishMessage, session); + processPublishMessage(mqttPublishMessage, session); + } }); } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java index 37f0dfe1..af925837 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java @@ -2,14 +2,14 @@ package org.smartboot.mqtt.common; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.smartboot.mqtt.common.enums.MqttMessageType; import org.smartboot.mqtt.common.enums.MqttVersion; import org.smartboot.mqtt.common.eventbus.EventBus; import org.smartboot.mqtt.common.eventbus.EventObject; import org.smartboot.mqtt.common.eventbus.EventType; import org.smartboot.mqtt.common.message.MqttMessage; import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; -import org.smartboot.mqtt.common.message.MqttPublishMessage; -import org.smartboot.mqtt.common.message.MqttVariableMessage; +import org.smartboot.mqtt.common.message.MqttPubQosMessage; import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; import org.smartboot.mqtt.common.protocol.MqttProtocol; import org.smartboot.mqtt.common.util.ValidateUtils; @@ -30,11 +30,6 @@ import java.util.function.Consumer; public abstract class AbstractSession { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSession.class); private static final int QOS0_PACKET_ID = 0; - /** - * req-resp 消息模式的处理回调 - */ - protected final Map responseConsumers = new ConcurrentHashMap<>(); - private final QosPublisher qosPublisher; /** * 用于生成当前会话的报文标识符 */ @@ -60,26 +55,22 @@ public abstract class AbstractSession { private MqttVersion mqttVersion; private InflightQueue inflightQueue; + protected Map>> responseConsumers = new ConcurrentHashMap<>(); - public AbstractSession(QosPublisher publisher, EventBus eventBus) { - this.qosPublisher = publisher; + public AbstractSession(EventBus eventBus) { this.eventBus = eventBus; } - public final synchronized void write(MqttPacketIdentifierMessage mqttMessage, Consumer> consumer) { - responseConsumers.put(mqttMessage.getVariableHeader().getPacketId(), new AckMessage(mqttMessage, consumer)); + public final synchronized void write(MqttPacketIdentifierMessage mqttMessage, Consumer> consumer) { + responseConsumers.put(mqttMessage.getVariableHeader().getPacketId(), consumer); write(mqttMessage); } - public Map getResponseConsumers() { - return responseConsumers; - } - - public final void notifyResponse(MqttVariableMessage message) { - AckMessage ackMessage = responseConsumers.remove(message.getVariableHeader().getPacketId()); - if (ackMessage != null) { - ackMessage.setDone(true); - ackMessage.getConsumer().accept(message); + public final void notifyResponse(MqttPacketIdentifierMessage message) { + if (message instanceof MqttPubQosMessage && message.getFixedHeader().getMessageType() != MqttMessageType.PUBREL) { + inflightQueue.notify((MqttPubQosMessage) message); + } else { + responseConsumers.remove(message.getVariableHeader().getPacketId()).accept(message); } } @@ -112,32 +103,6 @@ public abstract class AbstractSession { } } - public void publish(MqttPublishMessage message, Consumer consumer) { - publish(message, consumer, true); - } - - /** - * 若发送的Qos为0,则回调的consumer packetId为0 - */ - public void publish(MqttPublishMessage message, Consumer consumer, boolean autoFlush) { -// LOGGER.info("publish to client:{}, topic:{} packetId:{}", clientId, message.getMqttPublishVariableHeader().topicName(), message.getMqttPublishVariableHeader().packetId()); - switch (message.getFixedHeader().getQosLevel()) { - case AT_MOST_ONCE: - try { - write(message, autoFlush); - } finally { - consumer.accept(QOS0_PACKET_ID); - } - break; - case AT_LEAST_ONCE: - qosPublisher.publishQos1(this, message, consumer, autoFlush); - break; - case EXACTLY_ONCE: - qosPublisher.publishQos2(this, message, consumer, autoFlush); - break; - } - } - public long getLatestSendMessageTime() { return latestSendMessageTime; } @@ -163,9 +128,6 @@ public abstract class AbstractSession { packetIdCreator.set(0); return newPacketId(); } - if (responseConsumers.containsKey(packageId)) { - return newPacketId(); - } return packageId; } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java index a2600709..a54545a5 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java @@ -1,8 +1,8 @@ package org.smartboot.mqtt.common; -import org.smartboot.mqtt.common.message.MqttMessage; -import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; -import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; +import org.smartboot.mqtt.common.enums.MqttMessageType; +import org.smartboot.mqtt.common.enums.MqttQoS; +import org.smartboot.mqtt.common.message.MqttPublishMessage; import java.util.function.Consumer; @@ -14,40 +14,62 @@ public class AckMessage { /** * 原始消息 */ - private final MqttMessage originalMessage; + private final MqttPublishMessage originalMessage; + + private MqttMessageType expectMessageType; /** * 回调事件 */ - private Consumer> consumer; + private final Consumer consumer; - /** - * 执行状态 - */ - private boolean done; + private final long offset; - public AckMessage(MqttMessage originalMessage, Consumer> consumer) { + private boolean commit; + + private final int packetId; + + public AckMessage(MqttPublishMessage originalMessage, int packetId, Consumer consumer, long offset) { this.originalMessage = originalMessage; this.consumer = consumer; + this.offset = offset; + this.packetId = packetId; + if (originalMessage.getFixedHeader().getQosLevel() == MqttQoS.AT_LEAST_ONCE) { + this.expectMessageType = MqttMessageType.PUBACK; + } else if (originalMessage.getFixedHeader().getQosLevel() == MqttQoS.EXACTLY_ONCE) { + this.expectMessageType = MqttMessageType.PUBREC; + } } - public MqttMessage getOriginalMessage() { + public MqttPublishMessage getOriginalMessage() { return originalMessage; } - public Consumer getConsumer() { + public Consumer getConsumer() { return consumer; } - public void setConsumer(Consumer> consumer) { - this.consumer = consumer; + public MqttMessageType getExpectMessageType() { + return expectMessageType; + } + + public void setExpectMessageType(MqttMessageType expectMessageType) { + this.expectMessageType = expectMessageType; + } + + public long getOffset() { + return offset; + } + + public boolean isCommit() { + return commit; } - public boolean isDone() { - return done; + public void setCommit(boolean commit) { + this.commit = commit; } - public void setDone(boolean done) { - this.done = done; + public int getPacketId() { + return packetId; } } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index 32ecd628..717c43d3 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -1,62 +1,112 @@ package org.smartboot.mqtt.common; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.smartboot.mqtt.common.enums.MqttMessageType; +import org.smartboot.mqtt.common.enums.MqttQoS; +import org.smartboot.mqtt.common.enums.MqttVersion; +import org.smartboot.mqtt.common.message.MqttPubQosMessage; +import org.smartboot.mqtt.common.message.MqttPubRelMessage; import org.smartboot.mqtt.common.message.MqttPublishMessage; +import org.smartboot.mqtt.common.message.variable.MqttPubQosVariableHeader; +import org.smartboot.mqtt.common.message.variable.properties.ReasonProperties; import org.smartboot.mqtt.common.util.ValidateUtils; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + /** * @author 三刀(zhengjunweimail@163.com) * @version V1.0 , 2022/4/26 */ public class InflightQueue { - private final MqttPublishMessage[] queue; - private final long[] offsets; + private static final Logger LOGGER = LoggerFactory.getLogger(InflightQueue.class); + private final AckMessage[] queue; private int takeIndex; private int putIndex; private int count; - public InflightQueue(int size) { + private AtomicInteger packetId = new AtomicInteger(0); + + private final AbstractSession session; + + public InflightQueue(AbstractSession session, int size) { ValidateUtils.isTrue(size > 0, "inflight must >0"); - this.queue = new MqttPublishMessage[size]; - this.offsets = new long[size]; + this.queue = new AckMessage[size]; + this.session = session; } - public synchronized int offer(MqttPublishMessage mqttMessage, long offset) { + public synchronized int offer(MqttMessageBuilders.PublishBuilder publishBuilder, Consumer consumer, long offset) { if (count == queue.length) { return -1; } - queue[putIndex] = mqttMessage; - offsets[putIndex] = offset; + int id = packetId.incrementAndGet(); + publishBuilder.packetId(id); + MqttPublishMessage mqttMessage = publishBuilder.build(); + queue[putIndex] = new AckMessage(mqttMessage, id, consumer, offset); int index = putIndex++; if (putIndex == queue.length) { putIndex = 0; } count++; + session.write(mqttMessage); + // QOS直接响应 + if (mqttMessage.getFixedHeader().getQosLevel() == MqttQoS.AT_MOST_ONCE) { + consumer.accept(id); + } return index; } - public synchronized long commit(int commitIndex) { + public void notify(MqttPubQosMessage message) { + AckMessage ackMessage = queue[(message.getVariableHeader().getPacketId() - 1) % queue.length]; + ValidateUtils.isTrue(message.getFixedHeader().getMessageType() == ackMessage.getExpectMessageType(), "invalid message type"); + switch (message.getFixedHeader().getMessageType()) { + case PUBACK: { + ackMessage.getConsumer().accept(message.getVariableHeader().getPacketId()); + break; + } + case PUBREC: + ackMessage.setExpectMessageType(MqttMessageType.PUBCOMP); + //todo + ReasonProperties properties = null; + if (message.getVersion() == MqttVersion.MQTT_5) { + properties = new ReasonProperties(); + } + MqttPubQosVariableHeader variableHeader = new MqttPubQosVariableHeader(message.getVariableHeader().getPacketId(), properties); + MqttPubRelMessage pubRelMessage = new MqttPubRelMessage(variableHeader); + session.write(pubRelMessage); + break; + case PUBCOMP: + ackMessage.getConsumer().accept(message.getVariableHeader().getPacketId()); + break; + default: + throw new RuntimeException(); + } + } + + public synchronized long commit(int packetId) { + int commitIndex = (packetId - 1) % queue.length; + AckMessage ackMessage = queue[commitIndex]; + ValidateUtils.isTrue(ackMessage.getPacketId() == packetId, "invalid message"); + ackMessage.setCommit(true); + if (commitIndex != takeIndex) { - //转负数表示以提交 - offsets[commitIndex] = offsets[commitIndex] | Long.MIN_VALUE; return -1; } - long offset = offsets[takeIndex]; - offsets[takeIndex] = 0; queue[takeIndex++] = null; count--; if (takeIndex == queue.length) { takeIndex = 0; } - while (count > 0 && offsets[takeIndex] < 0) { - offset = offsets[takeIndex] & ~Long.MIN_VALUE; - offsets[takeIndex] = 0; + while (count > 0 && queue[takeIndex].isCommit()) { + ackMessage = queue[takeIndex]; queue[takeIndex++] = null; if (takeIndex == queue.length) { takeIndex = 0; } count--; } - return offset; + return ackMessage.getOffset(); } public int getCount() { diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java deleted file mode 100644 index b5a077b2..00000000 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/QosPublisher.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.smartboot.mqtt.common; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.smartboot.mqtt.common.enums.MqttMessageType; -import org.smartboot.mqtt.common.enums.MqttQoS; -import org.smartboot.mqtt.common.enums.MqttVersion; -import org.smartboot.mqtt.common.message.MqttMessage; -import org.smartboot.mqtt.common.message.MqttPubRelMessage; -import org.smartboot.mqtt.common.message.MqttPublishMessage; -import org.smartboot.mqtt.common.message.variable.MqttPubQosVariableHeader; -import org.smartboot.mqtt.common.message.variable.properties.ReasonProperties; -import org.smartboot.mqtt.common.util.ValidateUtils; - -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -public abstract class QosPublisher { - private static final Logger LOGGER = LoggerFactory.getLogger(QosPublisher.class); - - void publishQos1(AbstractSession session, MqttPublishMessage publishMessage, Consumer consumer, boolean autoFlush) { - MqttQoS qos = publishMessage.getFixedHeader().getQosLevel(); - ValidateUtils.notNull(qos == MqttQoS.AT_LEAST_ONCE, "qos is null"); - CompletableFuture future = new CompletableFuture<>(); - Integer cacheKey = publishMessage.getVariableHeader().getPacketId(); - //至少一次 - - session.responseConsumers.put(cacheKey, new AckMessage(publishMessage, message -> { - ValidateUtils.isTrue(message.getFixedHeader().getMessageType() == MqttMessageType.PUBACK, "invalid message type"); - future.complete(true); - session.responseConsumers.remove(cacheKey); - consumer.accept(publishMessage.getVariableHeader().getPacketId()); - })); - session.write(publishMessage, autoFlush); - //注册重试 - retry(future, session, publishMessage); - } - - void publishQos2(AbstractSession session, MqttPublishMessage publishMessage, Consumer consumer, boolean autoFlush) { - MqttQoS qos = publishMessage.getFixedHeader().getQosLevel(); - ValidateUtils.notNull(qos == MqttQoS.EXACTLY_ONCE, "qos is null"); - Integer cacheKey = publishMessage.getVariableHeader().getPacketId(); - CompletableFuture publishFuture = new CompletableFuture<>(); - //只有一次 - session.responseConsumers.put(cacheKey, new AckMessage(publishMessage, message -> { - ValidateUtils.isTrue(message.getFixedHeader().getMessageType() == MqttMessageType.PUBREC, "invalid message type"); - ValidateUtils.isTrue(Objects.equals(message.getVariableHeader().getPacketId(), publishMessage.getVariableHeader().getPacketId()), "invalid packetId"); - publishFuture.complete(true); - - //todo - ReasonProperties properties = null; - if (message.getVersion() == MqttVersion.MQTT_5) { - properties = new ReasonProperties(); - } - MqttPubQosVariableHeader variableHeader = new MqttPubQosVariableHeader(message.getVariableHeader().getPacketId(), properties); - MqttPubRelMessage pubRelMessage = new MqttPubRelMessage(variableHeader); - CompletableFuture pubRelFuture = new CompletableFuture<>(); - session.responseConsumers.put(cacheKey, new AckMessage(pubRelMessage, compMessage -> { - ValidateUtils.isTrue(compMessage.getFixedHeader().getMessageType() == MqttMessageType.PUBCOMP, "invalid message type"); - ValidateUtils.isTrue(Objects.equals(compMessage.getVariableHeader().getPacketId(), pubRelMessage.getVariableHeader().getPacketId()), "invalid packetId"); - pubRelFuture.complete(true); - consumer.accept(compMessage.getVariableHeader().getPacketId()); - })); - //注册重试 - retry(pubRelFuture, session, pubRelMessage); - session.write(pubRelMessage); - })); - retry(publishFuture, session, publishMessage); - session.write(publishMessage, autoFlush); - } - - protected abstract void retry(CompletableFuture future, AbstractSession session, MqttMessage mqttMessage); -} \ No newline at end of file diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPacketIdVariableHeader.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPacketIdVariableHeader.java index b52e06b6..6ba963fa 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPacketIdVariableHeader.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/message/variable/MqttPacketIdVariableHeader.java @@ -11,7 +11,7 @@ public abstract class MqttPacketIdVariableHeader e /** * 报文标识符 */ - private final int packetId; + private int packetId; public MqttPacketIdVariableHeader(int packetId, T properties) { super(properties); @@ -22,4 +22,8 @@ public abstract class MqttPacketIdVariableHeader e public int getPacketId() { return packetId; } + + public void setPacketId(int packetId) { + this.packetId = packetId; + } } -- Gitee From e09409d95e95e03bbf970dc1998928473988f69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 17 Mar 2023 20:48:15 +0800 Subject: [PATCH 22/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/broker/BrokerContextImpl.java | 19 ++++---- .../mqtt/broker/TopicSubscriber.java | 8 +--- .../impl/message/MemoryMessageStoreQueue.java | 2 +- .../org/smartboot/mqtt/client/MqttClient.java | 14 +++--- .../org/smartboot/mqtt/common/AckMessage.java | 6 +-- .../smartboot/mqtt/common/InflightQueue.java | 47 +++++++++++-------- .../mqtt/common/MqttMessageBuilders.java | 4 ++ 7 files changed, 55 insertions(+), 45 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java index 717747cb..7a198172 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/BrokerContextImpl.java @@ -290,7 +290,11 @@ public class BrokerContextImpl implements BrokerContext { // if (subscriber == BREAK) { // break; // } - subscriber.batchPublish(BrokerContextImpl.this); + try { + subscriber.batchPublish(BrokerContextImpl.this); + } catch (Exception e) { + LOGGER.error("batch publish exception:{}", e.getMessage()); + } } brokerTopic.getSemaphore().release(); if (version != brokerTopic.getVersion().get() && !subscribers.isEmpty()) { @@ -366,17 +370,12 @@ public class BrokerContextImpl implements BrokerContext { publishBuilder.publishProperties(new PublishProperties()); } InflightQueue inflightQueue = session.getInflightQueue(); - inflightQueue.offer(publishBuilder, integer -> { + inflightQueue.offer(publishBuilder, offset -> { LOGGER.info("publish retain to client:{} success ", session.getClientId()); - long offset = inflightQueue.commit(integer); - if (offset != -1) { - subscriber.setRetainConsumerOffset(offset + 1); - retainPushThreadPool.execute(task); - } else { - LOGGER.error("error..."); - } - + subscriber.setRetainConsumerOffset(offset + 1); + retainPushThreadPool.execute(task); }, storedMessage.getOffset()); + session.flush(); } }); } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index 526a2f12..98c83c9e 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -85,15 +85,11 @@ public class TopicSubscriber { } InflightQueue inflightQueue = mqttSession.getInflightQueue(); - int index = inflightQueue.offer(publishBuilder, packetId -> { + boolean suc = inflightQueue.offer(publishBuilder, offset -> { if (mqttQoS == MqttQoS.AT_MOST_ONCE) { nextConsumerOffset++; } //最早发送的消息若收到响应,则更新点位 - long offset = inflightQueue.commit(packetId); - if (offset == -1) { - return; - } commitNextConsumerOffset(offset + 1); if (persistenceMessage.isRetained()) { setRetainConsumerOffset(getRetainConsumerOffset() + 1); @@ -105,7 +101,7 @@ public class TopicSubscriber { } }, persistenceMessage.getOffset()); // 飞行队列已满 - if (index == -1) { + if (!suc) { // LOGGER.info("queue is full..." + expectConsumerOffset); return; } diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java index eccb87bb..762fa42c 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java @@ -17,7 +17,7 @@ class MemoryMessageStoreQueue { public void put(MqttPublishMessage msg) { PersistenceMessage message = new PersistenceMessage(msg, putOffset.incrementAndGet()); -// LOGGER.info("store message, offset:{}", msg.getOffset()); +// LOGGER.info("store message, offset:{}", message.getOffset()); store[(int) (message.getOffset() % store.length)] = message; } diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java index f08eea8c..e42ba2a2 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/MqttClient.java @@ -392,21 +392,23 @@ public class MqttClient extends AbstractSession { } } - private synchronized void publish(MqttMessageBuilders.PublishBuilder publishBuilder, Consumer consumer) { + private void publish(MqttMessageBuilders.PublishBuilder publishBuilder, Consumer consumer) { InflightQueue inflightQueue = getInflightQueue(); - int index = inflightQueue.offer(publishBuilder, packetId -> { - consumer.accept(packetId); + boolean suc = inflightQueue.offer(publishBuilder, offset -> { + consumer.accept(publishBuilder.getPacketId()); //最早发送的消息若收到响应,则更新点位 - long offset = inflightQueue.commit(packetId); if (offset != -1) { synchronized (MqttClient.this) { MqttClient.this.notifyAll(); } } }, 1); - if (index == -1) { + flush(); + if (!suc) { try { - wait(); + synchronized (this) { + wait(); + } } catch (InterruptedException e) { throw new RuntimeException(e); } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java index a54545a5..9d480c6d 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AckMessage.java @@ -20,7 +20,7 @@ public class AckMessage { /** * 回调事件 */ - private final Consumer consumer; + private final Consumer consumer; private final long offset; @@ -28,7 +28,7 @@ public class AckMessage { private final int packetId; - public AckMessage(MqttPublishMessage originalMessage, int packetId, Consumer consumer, long offset) { + public AckMessage(MqttPublishMessage originalMessage, int packetId, Consumer consumer, long offset) { this.originalMessage = originalMessage; this.consumer = consumer; this.offset = offset; @@ -45,7 +45,7 @@ public class AckMessage { } - public Consumer getConsumer() { + public Consumer getConsumer() { return consumer; } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index 717c43d3..3f670730 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -26,7 +26,7 @@ public class InflightQueue { private int putIndex; private int count; - private AtomicInteger packetId = new AtomicInteger(0); + private final AtomicInteger packetId = new AtomicInteger(0); private final AbstractSession session; @@ -36,25 +36,32 @@ public class InflightQueue { this.session = session; } - public synchronized int offer(MqttMessageBuilders.PublishBuilder publishBuilder, Consumer consumer, long offset) { - if (count == queue.length) { - return -1; - } - int id = packetId.incrementAndGet(); - publishBuilder.packetId(id); - MqttPublishMessage mqttMessage = publishBuilder.build(); - queue[putIndex] = new AckMessage(mqttMessage, id, consumer, offset); - int index = putIndex++; - if (putIndex == queue.length) { - putIndex = 0; + public boolean offer(MqttMessageBuilders.PublishBuilder publishBuilder, Consumer consumer, long offset) { + int id = 0; + MqttPublishMessage mqttMessage; + synchronized (this) { + if (count == queue.length) { + return false; + } + id = packetId.incrementAndGet(); + publishBuilder.packetId(id); + mqttMessage = publishBuilder.build(); + queue[putIndex++] = new AckMessage(mqttMessage, id, consumer, offset); + if (putIndex == queue.length) { + putIndex = 0; + } + count++; +// System.out.println("publish..."); + } - count++; - session.write(mqttMessage); + session.write(mqttMessage, false); // QOS直接响应 if (mqttMessage.getFixedHeader().getQosLevel() == MqttQoS.AT_MOST_ONCE) { - consumer.accept(id); + long offset1 = commit(id); + ValidateUtils.isTrue(offset1 == offset, "invalid offset"); + consumer.accept(offset); } - return index; + return true; } public void notify(MqttPubQosMessage message) { @@ -62,7 +69,8 @@ public class InflightQueue { ValidateUtils.isTrue(message.getFixedHeader().getMessageType() == ackMessage.getExpectMessageType(), "invalid message type"); switch (message.getFixedHeader().getMessageType()) { case PUBACK: { - ackMessage.getConsumer().accept(message.getVariableHeader().getPacketId()); + long offset = commit(message.getVariableHeader().getPacketId()); + ackMessage.getConsumer().accept(offset); break; } case PUBREC: @@ -77,14 +85,15 @@ public class InflightQueue { session.write(pubRelMessage); break; case PUBCOMP: - ackMessage.getConsumer().accept(message.getVariableHeader().getPacketId()); + long offset = commit(message.getVariableHeader().getPacketId()); + ackMessage.getConsumer().accept(offset); break; default: throw new RuntimeException(); } } - public synchronized long commit(int packetId) { + private synchronized long commit(int packetId) { int commitIndex = (packetId - 1) % queue.length; AckMessage ackMessage = queue[commitIndex]; ValidateUtils.isTrue(ackMessage.getPacketId() == packetId, "invalid message"); diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java index 13f647f9..f70d9843 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/MqttMessageBuilders.java @@ -78,6 +78,10 @@ public final class MqttMessageBuilders { return this; } + public int getPacketId() { + return packetId; + } + public MqttPublishMessage build() { MqttFixedHeader mqttFixedHeader = new MqttFixedHeader(MqttMessageType.PUBLISH, false, qos, retained); if (qos != MqttQoS.AT_LEAST_ONCE && qos != MqttQoS.EXACTLY_ONCE) { -- Gitee From 2d2765d748cfab0cdd35ad84c32ad28e454f2b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 17 Mar 2023 21:35:21 +0800 Subject: [PATCH 23/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/broker/TopicSubscriber.java | 9 ++-- .../broker/processor/PublishProcessor.java | 41 ++++++++----------- .../client/processor/PublishProcessor.java | 29 +++++-------- .../mqtt/common/AbstractSession.java | 6 +-- 4 files changed, 35 insertions(+), 50 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index 98c83c9e..1d989ad4 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -65,7 +65,7 @@ public class TopicSubscriber { mqttSession.flush(); } - private synchronized void publish0(BrokerContext brokerContext, int depth) { + private void publish0(BrokerContext brokerContext, int depth) { PersistenceProvider persistenceProvider = brokerContext.getProviders().getPersistenceProvider(); PersistenceMessage persistenceMessage = persistenceProvider.get(topic.getTopic(), nextConsumerOffset); if (persistenceMessage == null) { @@ -95,10 +95,9 @@ public class TopicSubscriber { setRetainConsumerOffset(getRetainConsumerOffset() + 1); } commitRetainConsumerTimestamp(persistenceMessage.getCreateTime()); - if (inflightQueue.getCount() == 0) { - publish0(brokerContext, 0); - mqttSession.flush(); - } +// if (inflightQueue.getCount() == 0) { + publish0(brokerContext, 0); +// } }, persistenceMessage.getOffset()); // 飞行队列已满 if (!suc) { diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java index 60aacf54..d997d6ab 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/processor/PublishProcessor.java @@ -10,17 +10,13 @@ import org.smartboot.mqtt.broker.eventbus.ServerEventType; import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.enums.MqttReasonCode; import org.smartboot.mqtt.common.enums.MqttVersion; -import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; import org.smartboot.mqtt.common.message.MqttPubAckMessage; import org.smartboot.mqtt.common.message.MqttPubCompMessage; import org.smartboot.mqtt.common.message.MqttPubRecMessage; import org.smartboot.mqtt.common.message.MqttPublishMessage; -import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; import org.smartboot.mqtt.common.message.variable.MqttPubQosVariableHeader; import org.smartboot.mqtt.common.message.variable.properties.ReasonProperties; -import java.util.function.Consumer; - /** * 发布Topic * @@ -79,7 +75,7 @@ public class PublishProcessor extends AuthorizedMqttProcessor>() { - @Override - public void accept(MqttPacketIdentifierMessage message) { - //发送pubRel消息。 - //todo - MqttPubQosVariableHeader qosVariableHeader; - //todo - byte code = 0; - if (code != 0) { - ReasonProperties properties = new ReasonProperties(); - qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), properties); - qosVariableHeader.setReasonCode(code); - } else { - qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), null); - } - MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); - session.write(pubRelMessage); - // 消息投递至消息总线 - context.getEventBus().publish(ServerEventType.RECEIVE_PUBLISH_MESSAGE, EventObject.newEventObject(session, mqttPublishMessage)); + session.write(pubRecMessage, message -> { + //发送pubRel消息。 + //todo + MqttPubQosVariableHeader qosVariableHeader; + //todo + byte code = 0; + if (code != 0) { + ReasonProperties properties = new ReasonProperties(); + qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), properties); + qosVariableHeader.setReasonCode(code); + } else { + qosVariableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), null); } + MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); + session.write(pubRelMessage, false); + // 消息投递至消息总线 + context.getEventBus().publish(ServerEventType.RECEIVE_PUBLISH_MESSAGE, EventObject.newEventObject(session, mqttPublishMessage)); }); } } diff --git a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java index 80625187..dd450179 100644 --- a/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java +++ b/smart-mqtt-client/src/main/java/org/smartboot/mqtt/client/processor/PublishProcessor.java @@ -7,19 +7,15 @@ import org.smartboot.mqtt.client.Subscribe; import org.smartboot.mqtt.common.TopicToken; import org.smartboot.mqtt.common.enums.MqttQoS; import org.smartboot.mqtt.common.enums.MqttVersion; -import org.smartboot.mqtt.common.message.MqttPacketIdentifierMessage; import org.smartboot.mqtt.common.message.MqttPubAckMessage; import org.smartboot.mqtt.common.message.MqttPubCompMessage; import org.smartboot.mqtt.common.message.MqttPubRecMessage; import org.smartboot.mqtt.common.message.MqttPublishMessage; -import org.smartboot.mqtt.common.message.variable.MqttPacketIdVariableHeader; import org.smartboot.mqtt.common.message.variable.MqttPubQosVariableHeader; import org.smartboot.mqtt.common.message.variable.MqttPublishVariableHeader; import org.smartboot.mqtt.common.message.variable.properties.ReasonProperties; import org.smartboot.mqtt.common.util.TopicTokenUtil; -import java.util.function.Consumer; - /** * 发布Topic * @@ -83,7 +79,7 @@ public class PublishProcessor implements MqttProcessor { } MqttPubQosVariableHeader variableHeader = new MqttPubQosVariableHeader(mqttPublishMessage.getVariableHeader().getPacketId(), properties); MqttPubAckMessage pubAckMessage = new MqttPubAckMessage(variableHeader); - mqttClient.write(pubAckMessage); + mqttClient.write(pubAckMessage, false); } private void processQos2(MqttClient session, MqttPublishMessage mqttPublishMessage) { @@ -96,20 +92,17 @@ public class PublishProcessor implements MqttProcessor { MqttPubQosVariableHeader variableHeader = new MqttPubQosVariableHeader(messageId, properties); MqttPubRecMessage pubRecMessage = new MqttPubRecMessage(variableHeader); - session.write(pubRecMessage, new Consumer>() { - @Override - public void accept(MqttPacketIdentifierMessage message) { - //todo - ReasonProperties reasonProperties = null; - if (mqttPublishMessage.getVersion() == MqttVersion.MQTT_5) { - reasonProperties = new ReasonProperties(); - } - MqttPubQosVariableHeader qosVariableHeader = new MqttPubQosVariableHeader(message.getVariableHeader().getPacketId(), reasonProperties); - MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); - session.write(pubRelMessage); - - processPublishMessage(mqttPublishMessage, session); + session.write(pubRecMessage, message -> { + //todo + ReasonProperties reasonProperties = null; + if (mqttPublishMessage.getVersion() == MqttVersion.MQTT_5) { + reasonProperties = new ReasonProperties(); } + MqttPubQosVariableHeader qosVariableHeader = new MqttPubQosVariableHeader(message.getVariableHeader().getPacketId(), reasonProperties); + MqttPubCompMessage pubRelMessage = new MqttPubCompMessage(qosVariableHeader); + session.write(pubRelMessage, false); + + processPublishMessage(mqttPublishMessage, session); }); } diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java index af925837..5ab9f529 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/AbstractSession.java @@ -61,9 +61,9 @@ public abstract class AbstractSession { this.eventBus = eventBus; } - public final synchronized void write(MqttPacketIdentifierMessage mqttMessage, Consumer> consumer) { + public final void write(MqttPacketIdentifierMessage mqttMessage, Consumer> consumer) { responseConsumers.put(mqttMessage.getVariableHeader().getPacketId(), consumer); - write(mqttMessage); + write(mqttMessage, false); } public final void notifyResponse(MqttPacketIdentifierMessage message) { @@ -93,7 +93,7 @@ public abstract class AbstractSession { } } - public final synchronized void write(MqttMessage mqttMessage) { + public final void write(MqttMessage mqttMessage) { write(mqttMessage, true); } -- Gitee From 609884fa208cbf8b699e535b93e31e7a770bff4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Fri, 17 Mar 2023 22:35:45 +0800 Subject: [PATCH 24/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/smartboot/mqtt/broker/TopicSubscriber.java | 2 +- smart-mqtt-broker/src/main/resources/smart-mqtt.yaml | 2 +- .../main/java/org/smartboot/mqtt/common/InflightQueue.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index 1d989ad4..b451949d 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -75,7 +75,7 @@ public class TopicSubscriber { return; } if (depth > 16) { - LOGGER.info("退出递归..."); +// LOGGER.info("退出递归..."); return; } diff --git a/smart-mqtt-broker/src/main/resources/smart-mqtt.yaml b/smart-mqtt-broker/src/main/resources/smart-mqtt.yaml index 940a423b..7e8ba1b9 100644 --- a/smart-mqtt-broker/src/main/resources/smart-mqtt.yaml +++ b/smart-mqtt-broker/src/main/resources/smart-mqtt.yaml @@ -1,7 +1,7 @@ broker: name: smart-mqtt # 集群模式需确保唯一性 port: 1883 - maxInflight: 8 + maxInflight: 256 openapi: port: 18083 host: 0.0.0.0 diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index 3f670730..f40653e1 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -58,7 +58,7 @@ public class InflightQueue { // QOS直接响应 if (mqttMessage.getFixedHeader().getQosLevel() == MqttQoS.AT_MOST_ONCE) { long offset1 = commit(id); - ValidateUtils.isTrue(offset1 == offset, "invalid offset"); +// ValidateUtils.isTrue(offset1 == -1 || offset1 == offset, "invalid offset"); consumer.accept(offset); } return true; @@ -82,7 +82,7 @@ public class InflightQueue { } MqttPubQosVariableHeader variableHeader = new MqttPubQosVariableHeader(message.getVariableHeader().getPacketId(), properties); MqttPubRelMessage pubRelMessage = new MqttPubRelMessage(variableHeader); - session.write(pubRelMessage); + session.write(pubRelMessage, false); break; case PUBCOMP: long offset = commit(message.getVariableHeader().getPacketId()); -- Gitee From 09daf6d96b1c5f7efed7ff42edb89a4ddebd9c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 18 Mar 2023 17:27:21 +0800 Subject: [PATCH 25/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/smartboot/mqtt/common/InflightQueue.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index f40653e1..f1388798 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -44,6 +44,10 @@ public class InflightQueue { return false; } id = packetId.incrementAndGet(); + // 16位无符号最大值65535 + if (id > 65535) { + id = packetId.getAndSet(1); + } publishBuilder.packetId(id); mqttMessage = publishBuilder.build(); queue[putIndex++] = new AckMessage(mqttMessage, id, consumer, offset); -- Gitee From f801ae3ab8e7c0182ff8c31b83af68490e0c5970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 18 Mar 2023 19:51:19 +0800 Subject: [PATCH 26/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/smartboot/mqtt/broker/TopicSubscriber.java | 4 ++-- .../provider/impl/message/MemoryMessageStoreQueue.java | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index b451949d..4907a950 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -87,7 +87,7 @@ public class TopicSubscriber { InflightQueue inflightQueue = mqttSession.getInflightQueue(); boolean suc = inflightQueue.offer(publishBuilder, offset -> { if (mqttQoS == MqttQoS.AT_MOST_ONCE) { - nextConsumerOffset++; + nextConsumerOffset = persistenceMessage.getOffset() + 1; } //最早发送的消息若收到响应,则更新点位 commitNextConsumerOffset(offset + 1); @@ -106,7 +106,7 @@ public class TopicSubscriber { } long start = System.currentTimeMillis(); if (mqttQoS != MqttQoS.AT_MOST_ONCE) { - nextConsumerOffset++; + nextConsumerOffset = persistenceMessage.getOffset() + 1; } long cost = System.currentTimeMillis() - start; diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java index 762fa42c..2035f076 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/provider/impl/message/MemoryMessageStoreQueue.java @@ -23,10 +23,15 @@ class MemoryMessageStoreQueue { public PersistenceMessage get(long offset) { PersistenceMessage storedMessage = store[(int) (offset % store.length)]; - if (storedMessage == null) { + if (storedMessage != null && storedMessage.getOffset() == offset) { + return storedMessage; + } + if (offset < putOffset.get()) { +// System.out.println("skip..."); + return store[(int) (putOffset.get() % store.length)]; + } else { return null; } - return storedMessage.getOffset() == offset ? storedMessage : null; } /** -- Gitee From 80345c07e6a5675a912b7e8f6342c244c2dc36bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 18 Mar 2023 20:58:26 +0800 Subject: [PATCH 27/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/smartboot/mqtt/common/InflightQueue.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index f1388798..fc3979fa 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -46,7 +46,8 @@ public class InflightQueue { id = packetId.incrementAndGet(); // 16位无符号最大值65535 if (id > 65535) { - id = packetId.getAndSet(1); + id = id % queue.length; + packetId.set(id); } publishBuilder.packetId(id); mqttMessage = publishBuilder.build(); -- Gitee From bd4d140674d6792b248e337276ef3d73c224cdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 18 Mar 2023 21:05:26 +0800 Subject: [PATCH 28/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/smartboot/mqtt/common/InflightQueue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java index fc3979fa..fa38e953 100644 --- a/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java +++ b/smart-mqtt-common/src/main/java/org/smartboot/mqtt/common/InflightQueue.java @@ -46,7 +46,7 @@ public class InflightQueue { id = packetId.incrementAndGet(); // 16位无符号最大值65535 if (id > 65535) { - id = id % queue.length; + id = id % queue.length + queue.length; packetId.set(id); } publishBuilder.packetId(id); -- Gitee From 790af87fc8bb5dfda058c80f7363ccfbffe288ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=88=80?= Date: Sat, 18 Mar 2023 22:58:16 +0800 Subject: [PATCH 29/29] =?UTF-8?q?=E9=87=8D=E6=9E=84push=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 +- .../main/java/org/smartboot/mqtt/broker/TopicSubscriber.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9b886d23..f00444ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -51,6 +51,6 @@ services: options: max-size: "100m" max-file: "1" - command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=2000 -Dqos=2 -Dpublisher=2 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Subscribe + command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=2000 -Dqos=2 -Dpublisher=10 -Dcount=1 -Dpayload=128 org.smartboot.bench.mqtt.Subscribe # command: java -cp smart-mqtt-bench.jar -Dhost=mqtt-broker -Dconnect=1000 -Dqos=2 -Dcount=3 -Dpayload=128 org.smartboot.bench.mqtt.Publish version: '3.7' \ No newline at end of file diff --git a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java index 4907a950..2e2ce334 100644 --- a/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java +++ b/smart-mqtt-broker/src/main/java/org/smartboot/mqtt/broker/TopicSubscriber.java @@ -60,6 +60,9 @@ public class TopicSubscriber { } public void batchPublish(BrokerContext brokerContext) { + if (mqttSession.isDisconnect()) { + return; + } semaphore.release(); publish0(brokerContext, 0); mqttSession.flush(); -- Gitee