物联网 基于netty核心实战-握手与认证

物联网 基于netty核心实战-握手与认证

简述

MQTT PUBLISH 报文 的二进制结构(固定头、可变头、有效载荷),并基于 Netty 实现一个支持 QoS 0 的发布/订阅 Broker

源码(netty-sample-05-auth)

https://gitee.com/kcnf-iot/iot-sample/tree/master/netty/netty-sample-05

协议结构

MQTT 报文结构 Netty 中的对应 Java 类 关键字段/作用
固定报头 (Fixed Header) MqttFixedHeader 包含 messageType (如 CONNECT), qosLevel, isRetain 等标志位
可变报头 (Variable Header) MqttConnectVariableHeader 包含协议名、版本号、连接标志(如 Clean Session)、保活时间
有效载荷 (Payload) MqttConnectPayload 包含实际数据,如客户端ID、遗嘱消息、用户名和密码
完整连接请求 MqttConnectMessage 一个对象就包含了上述三部分,可以直接在处理器中使用

简易demo

服务端
复制代码
package com.jysemel.iot;

import com.jysemel.iot.handler.MqttAuthHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;

public class MqttAuthServer {
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline p = ch.pipeline();
                            // (A) 使用 Netty 内置的 MqttDecoder
                            p.addLast("mqttDecoder", new MqttDecoder(1024));
                            // (B) 使用单例的 MqttEncoder
                            p.addLast("mqttEncoder", MqttEncoder.INSTANCE);
                            // (C) 实现我们自己的业务逻辑处理器
                            p.addLast("authHandler", new MqttAuthHandler());
                        }
                    });
            ChannelFuture f = b.bind(1883).sync();
            System.out.println("MQTT Auth Server started on port 1883");
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
客户端
复制代码
package com.jysemel.iot;

import com.jysemel.iot.handler.MqttAuthClientHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;

public class MqttAuthClient {
    public static void main(String[] args) throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast("mqttDecoder", new MqttDecoder(1024));
                            p.addLast("mqttEncoder", MqttEncoder.INSTANCE);
                            p.addLast("clientHandler", new MqttAuthClientHandler());
                        }
                    });
            ChannelFuture f = b.connect("127.0.0.1", 1883).sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}
相关推荐
乌暮6 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
YDS8296 小时前
Small Spring IOC篇:容器事件及其监听器
java·spring
金銀銅鐵6 小时前
带您看懂字节码指令(三):一行加法里有什么
java·jvm
文丑颜不良啊6 小时前
LeetCode2921~2940题目解析
java·leetcode
我不会起名字3226 小时前
未接入最终读上限的参数:`websocketMaxMsgLen` 与 12.5 倍差距
后端·websocket·go·即时通讯·im·故障排查
一条Go7 小时前
接收方合并去重:同一个人为什么只该收到一次通知
后端·架构·github
北漂人Java7 小时前
基于 Spring AI Alibaba WorkFlow 构建 Java 生产级 AI Agent
java·人工智能·spring
张一凡937 小时前
给 Coding Agent 加一道"架构闸门":Jin 是如何做到"先审架构、再写代码、不漂移"的
前端·后端·agent
Jvav练习生7 小时前
AI Agent 总在关键时刻“失忆”翻车?一文讲透上下文工程(附可运行 Python 代码)
后端
用户112936112197 小时前
编译全绿,上线就崩:MyBatis 五层方法名大小写埋下的坑
java