从零开始搭建属于自己的物联网平台(三)基于netty实现mqtt server网关

/\*\*

* 网关状态
*
* @return 网关状态
*/
Boolean status();
}


#### 使用netty实现mqtt server


这里使用netty来实现mqtt server。



package com.soft863.gateway.mqtt;

import com.soft863.gateway.DeviceGateway;
import com.soft863.gateway.message.codec.DefaultTransport;
import com.soft863.gateway.message.codec.Transport;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.ResourceLeakDetector;
import lombok.extern.slf4j.Slf4j;

/**
* @Author: 刘华林
* @Date: 21-3-9 下午20:07
* @Version 2.0
*/
@Slf4j
public class MqttServerGateway implements DeviceGateway {

/\*\* 网关ID(为后续多实例扩展) \*/
private String id;
/\*\* 服务端口 \*/
private Integer port;
/\*\* netty boos线程 \*/
private Integer bossGroupThreadCount;
/\*\* netty woreker线程数 推荐设置为核数\*2 \*/
private Integer workerGroupThreadCount;
/\*\* 网关状态 true 启动 false 关闭 \*/
private Boolean status;
/\*\*

* DISABLED(禁用): 不进行内存泄露的检测;
*
* SIMPLE(操作简单): 抽样检测,且只对部分方法调用进行记录,消耗较小,有泄漏时可能会延迟报告,默认级别;
*
* ADVANCED(高级): 抽样检测,记录对象最近几次的调用记录,有泄漏时可能会延迟报告;
*
* PARANOID(偏执): 每次创建一个对象时都进行泄露检测,且会记录对象最近的详细调用记录。是比较激进的内存泄露检测级别,消耗最大,建议只在测试时使用。
*/
private String leakDetectorLevel;
/**
* 最大消息长度
*/
private Integer maxPayloadSize;

private ChannelFuture channelFuture;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;

public MqttServerGateway(String id,
                         Integer port,
                         Integer bossGroupThreadCount,
                         Integer workerGroupThreadCount,
                         String leakDetectorLevel,
                         Integer maxPayloadSize) {
    this.id = id;
    this.port = port;
    this.bossGroupThreadCount = bossGroupThreadCount;
    this.workerGroupThreadCount = workerGroupThreadCount;
    this.leakDetectorLevel = leakDetectorLevel;
    this.maxPayloadSize = maxPayloadSize;
}

@Override
public String getId() {
    return this.id;
}

@Override
public Integer getPort() {
    return this.port;
}

@Override
public Transport getTransport() {
    return DefaultTransport.MQTT;
}

@Override
public void startup() {
    log.info("Setting resource leak detector level to {}", leakDetectorLevel);
    ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.valueOf(leakDetectorLevel.toUpperCase()));

    log.info("Starting Server");
    //创建boss线程组 用于服务端接受客户端的连接
    bossGroup = new NioEventLoopGroup(bossGroupThreadCount);
    // 创建 worker 线程组 用于进行 SocketChannel 的数据读写
    workerGroup = new NioEventLoopGroup(workerGroupThreadCount);
    // 创建 ServerBootstrap 对象
    ServerBootstrap b = new ServerBootstrap();
    //设置使用的EventLoopGroup
    b.group(bossGroup, workerGroup)
            //设置要被实例化的为 NioServerSocketChannel 类
            .channel(NioServerSocketChannel.class)
            // 设置 NioServerSo
  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在基于Netty搭建MQTT服务器时,可以通过以下步骤设置用户名密码: 1. 创建一个自定义的MqttAuthenticator类,并实现MqttAuthenticator接口。 2. 在MqttAuthenticator类中实现authenticate方法,该方法接收一个MqttConnectMessage对象和一个ChannelHandlerContext对象作为参数。 3. 在authenticate方法中,可以获取MqttConnectMessage对象中的用户名和密码,并进行验证。 4. 如果用户名和密码正确,则在ChannelHandlerContext对象中设置属性,以便后续的消息处理器可以获取这些属性。 5. 如果用户名和密码不正确,则可以通过ChannelHandlerContext对象关闭连接。 以下是一个例子: ``` public class MyMqttAuthenticator implements MqttAuthenticator { @Override public void authenticate(MqttConnectMessage connectMessage, ChannelHandlerContext ctx, Promise<Void> promise) throws Exception { String username = connectMessage.payload().userName(); String password = connectMessage.payload().password(); if (isValidUsernameAndPassword(username, password)) { // 设置属性,以便后续的消息处理器可以获取这些属性 ctx.channel().attr(AttributeKey.valueOf("username")).set(username); ctx.channel().attr(AttributeKey.valueOf("password")).set(password); promise.setSuccess(null); } else { // 关闭连接 ctx.close(); promise.setFailure(new MqttConnectException(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD)); } } private boolean isValidUsernameAndPassword(String username, String password) { // TODO: 验证用户名和密码是否正确 return true; } } ``` 在MqttServerInitializer类中,可以将自定义的MqttAuthenticator类添加到MqttServerHandler类中: ``` public class MqttServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { MqttServer mqttServer = new MqttServer(); MqttServerHandler mqttHandler = new MqttServerHandler(mqttServer); mqttHandler.setAuthenticator(new MyMqttAuthenticator()); // 添加自定义的MqttAuthenticator类 ch.pipeline().addLast(new MqttDecoder(), new MqttEncoder(), mqttHandler); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值