GithubHelp home page GithubHelp logo

amazingwujun / mqttx Goto Github PK

View Code? Open in Web Editor NEW
304.0 16.0 101.0 780 KB

MQTTX Project 完整实现 mqttv3.1.1 协议,旨在提供易于使用且性能优异的 mqtt broker

License: Apache License 2.0

Java 100.00%
mqtt netty docker cluster springboot broker share-topic mqttx iot-application websocket

mqttx's Introduction

Hi there 👋

  • ⚡ Java / c++ / golang / js
  • 🌱 I’m currently learning c++ and qt
  • 🤔 I’m looking for help with my MQTTX Project
  • 💬 Ask me about mqtt\netty\java\springboot
  • 📫 How to reach me: [email protected]

Jun's github stats

mqttx's People

Contributors

amazingwujun avatar dependabot[bot] avatar nightmare815 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mqttx's Issues

监听MQTT客户端状态(在线、离线)

一、业务场景
监测MQTT客户端状态(在线、离线)。

其实这个在MQTT协议中已经给出系统主题,MQTT服务端可以知道客户端的任何情况,比如:什么时候上线和下线。

二、解决方案
$SYS/brokers/${node}/clients/${clientid}/connected:上线事件。当某客户端上线时,会向该主题(Topic)发布消息

$SYS/brokers/${node}/clients/${clientid}/disconnected:掉线事件。当某客户端掉线时,会向该主题(Topic)发布消息

当然在开发的时候我们订阅两个主题比较麻烦,可以采用主题通配符模式直接订阅一个主题即可:$SYS/broker/+/clients/#

系统主题监测多台MQTT服务端状态

一、业务场景
监测多台MQTT服务端状态。

二、实现方案

普通系统主题模式:$SYS/broker/{brokerId}/ status

主题通配符模式:$SYS/broker/+/status

移除测试模式

在提供 docker 镜像后,用户可以便捷启动应用,测试模式 没有存在的必要了。

mqtt连接数上不去

SubscriptionServiceImpl 中topic-set-key 使用set结构,但是redis的set结构内容超过1000以上就会比较慢,因为set结构的sadd方法的时间复杂度是o(n),是否考虑只使用内存,或者其他的数据结构,优化。

监听MQTT客户端状态(在线、离线)

一、业务场景
监测MQTT客户端状态(在线、离线)。

其实这个在MQTT协议中已经给出系统主题,MQTT服务端可以知道客户端的任何情况,比如:什么时候上线和下线。

二、解决方案
$SYS/brokers/${node}/clients/${clientid}/connected:上线事件。当某客户端上线时,会向该主题(Topic)发布消息

$SYS/brokers/${node}/clients/${clientid}/disconnected:掉线事件。当某客户端掉线时,会向该主题(Topic)发布消息

订阅两个主题比较麻烦,可以采用主题通配符模式直接订阅一个主题即可:$SYS/broker/+/client/#

出现如下报错信息如何解决?

Exception in thread "pool-1-thread-1" java.lang.IllegalArgumentException: messageId: 503316480 (expected: 1 ~ 65535)
at io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader.from(MqttMessageIdVariableHeader.java:31)
at com.jun.mqttx.broker.handler.ConnectHandler.lambda$republish$5(ConnectHandler.java:290)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at com.jun.mqttx.broker.handler.ConnectHandler.republish(ConnectHandler.java:286)
at com.jun.mqttx.broker.handler.ConnectHandler.lambda$process0$3(ConnectHandler.java:253)
at com.jun.mqttx.utils.GlobalExecutor$DefaultTask.run(GlobalExecutor.java:86)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

这段代码是不是有点低效

Set allTopic = stringRedisTemplate.opsForSet().members(topicSetKey);
if (CollectionUtils.isEmpty(allTopic)) {
return Collections.EMPTY_LIST;
}

    List<ClientSub> clientSubList = new ArrayList<>();
    allTopic.stream()
            .filter(e -> TopicUtils.match(topic, e))
            .forEach(e -> {
                Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(topicPrefix + e);
                if (!CollectionUtils.isEmpty(entries)) {
                    entries.forEach((k, v) -> {
                        String key = (String) k;
                        String val = (String) v;
                        clientSubList.add(new ClientSub(key, Integer.parseInt(val), e));
                    });
                }
            });

    return clientSubList;

netty为什么没有启用业务线程池处理MqttMessage,是有特别的考虑吗?

        // 用户名及密码校验
        if (variableHeader.hasPassword() && variableHeader.hasUserName()) {
            authenticationService.asyncAuthenticate(ClientAuthDTO.of(clientId, username, password))
                    .thenAccept(authentication -> {
                        if (authentication == null) {
                            // authentication 是有可能为 null 的
                            // 比如 认证服务 response http status = 200, 但是响应内容为空
                            authentication = Authentication.of(clientId);
                        } else {
                            authentication.setClientId(clientId); // 置入 clientId
                        }
                        process0(ctx, msg, authentication);
                    })
                    .exceptionally(throwable -> {
                        MqttConnAckMessage mqttConnAckMessage;
                        if (throwable.getCause() instanceof AuthenticationException) {
                            mqttConnAckMessage = MqttMessageBuilders.connAck()
                                    .sessionPresent(false)
                                    .returnCode(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD)
                                    .build();
                        } else {
                            mqttConnAckMessage = MqttMessageBuilders.connAck()
                                    .sessionPresent(false)
                                    .returnCode(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE)
                                    .build();
                        }
                        log.error(String.format("client[id: %s, username: %s]登入失败", clientId, username), throwable);

                        // 告知客户端并关闭连接
                        ctx.writeAndFlush(mqttConnAckMessage);
                        ctx.close();
                        return null;
                    });
        } else {
            process0(ctx, msg, Authentication.of(clientId));
        }

类似处理CONNECT类型消息,会阻塞IO线程。

nextMessageId的疑问

public synchronized static int nextMessageId(String clientId) {
    Integer id = map.computeIfAbsent(clientId, k -> 1);
    if ((id & 0xffff) == 0) {
        id++;
    }
    map.put(clientId, id);
    return id;
}

com.jun.mqttx.utils.MessageIdUtils里
这个地方id & 0xffff == 0的时候id自增,那每次调用返回的都是1,是不是应该 != 0的时候 id++?

mqttx 由最低支持 jdk1.8 转到 jdk11

jdk11jdk8 还是进化了不少的,尤其是 ZGC 的支持, 另外看 springboot 对JDK版本的支持,JDK11 是大势所趋啊,不知道大家的意见是什么。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.