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

            .childHandler(new MqttTransportServerInitializer(maxPayloadSize));
    // 绑定端口,并同步等待成功,即启动服务端
    try {
        channelFuture = b.bind(port).sync();
        status = true;
    } catch (InterruptedException e) {
        log.error("Server starting error");
        status = false;
    }
    log.info("Server started!");
}

@Override
public void shutdown() {
    log.info("Stopping Server");
    workerGroup.shutdownGracefully();
    bossGroup.shutdownGracefully();
    status = false;
    log.info("server stopped!");

}

@Override
public Boolean status() {
    return this.status;
}

}


##### 消息处理


当netty接收到设备上行消息之后,进行解析处理,将消息广播到消息总线,后续设备订阅消息总线中的内容,再进行业务处理。



package com.soft863.gateway.mqtt;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;

/**
* @Author: 刘华林
* @Date: 19-4-3 下午3:26
* @Version 1.0
*/
public class MqttTransportServerInitializer extends ChannelInitializer {

private final int maxPayloadSize;

public MqttTransportServerInitializer(int maxPayloadSize) {
    this.maxPayloadSize = maxPayloadSize;
}

@Override
protected void initChannel(SocketChannel socketChannel) {
    ChannelPipeline pipeline = socketChannel.pipeline();
    pipeline.addLast("decoder", new MqttDecoder(maxPayloadSize));
    pipeline.addLast("encoder", MqttEncoder.INSTANCE);
    MqttTransportHandler handler = new MqttTransportHandler();
    pipeline.addLast(handler);
    socketChannel.closeFuture().addListener(handler);

}

}



package com.soft863.gateway.mqtt;

import com.alibaba.fastjson.JSON;
import com.soft863.gateway.DeviceInstance;
import com.soft863.gateway.auth.DeviceAuthenticator;
import com.soft863.gateway.matcher.TopicMatcher;
import com.soft863.gateway.message.DefaultDeviceMsg;
import com.soft863.gateway.message.Message;
import com.soft863.gateway.message.codec.DefaultTransport;
import com.soft863.gateway.message.codec.FromDeviceMessageContext;
import com.soft863.gateway.message.codec.mqtt.SimpleMqttMessage;
import com.soft863.gateway.mqtt.adapter.JsonMqttAdaptor;
import com.soft863.gateway.protocol.DeviceMessageCodec;
import com.soft863.gateway.protocol.ProtocolSupport;
import com.soft863.gateway.registry.DeviceSession;
import com.soft863.gateway.registry.MemoryProtocolSupportRegistry;
import com.soft863.gateway.tsl.adaptor.AdaptorException;
import com.soft863.gateway.util.ApplicationUtil;
import com.soft863.stream.core.eventbus.EventBus;
import com.soft863.stream.core.eventbus.message.AdapterMessage;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.mqtt.*;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.u

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值