Spring Boot整合Netty(二):注入Service

1、添加依赖

        <!--netty-->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.24.Final</version>
            <scope>compile</scope>
        </dependency>

2、创建TcpServer


@Slf4j
@Component
@Order(value = 1)
public class TcpServer implements CommandLineRunner {

    @Value("${netty.ip}")
    private String ip;

    @Value("${netty.port}")
    private int tcpPort;

    @Autowired
    private ProduceOrderService produceOrderService;

    @Autowired
    private TestRecordTopService testRecordTopService;

    @Autowired
    private TestRecordAllService testRecordAllService;

    @Autowired
    private ProduceOrderLogService produceOrderLogService;

    @Async
    @Override
    public void run(String... args) {
        start(ip, tcpPort);
    }

    public void start(String ip, int port) {
        // master reactor
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        // sub reactor
        EventLoopGroup workGroup = new NioEventLoopGroup();

        ChannelFuture f;
        try {
            // start
            ServerBootstrap bootstrap = new ServerBootstrap();
            // install NioEventLoopGroup
            bootstrap.group(bossGroup, workGroup)
                    // set channel type NIO
                    .channel(NioServerSocketChannel.class)
                    // set connect params
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childOption(ChannelOption.TCP_NODELAY, true)
                    // set in/out event handler
                    .childHandler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) {
                            // 添加分隔符解码器
                            ch.pipeline().addFirst(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Unpooled.copiedBuffer("&&".getBytes())));
                            ch.pipeline().addLast(new TcpMsgOutHandler());
                            ch.pipeline().addLast(new TcpActiveHandler());
                            ch.pipeline().addLast(new TcpMsgInHandler(produceOrderService, testRecordTopService, testRecordAllService, produceOrderLogService));
                        }
                    });
            // bind port
            f = bootstrap.bind(ip, port).sync();
            if (f.isSuccess()) {
                log.info("start tcp server success: {}", port);
            } else {
                log.warn("start tcp server failed: {}", f.cause().getMessage());
            }
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("start tcp server error: {}", e.getMessage());
        } finally {
            workGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

3、Handler

@Slf4j
@ChannelHandler.Sharable
public class TcpActiveHandler extends ChannelInboundHandlerAdapter {

    private final static AtomicLong activeCount = new AtomicLong(0);

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("active client count: {}", activeCount.addAndGet(1));
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("active client count: {}", activeCount.decrementAndGet());
    }

}
public class TcpMsgOutHandler extends ChannelOutboundHandlerAdapter {

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
        ctx.writeAndFlush(Unpooled.copiedBuffer(((String) msg).getBytes(StandardCharsets.UTF_8)));
    }
}

@Slf4j
public class TcpMsgInHandler extends ChannelInboundHandlerAdapter {

    private final ProduceOrderService produceOrderService;
    private final TestRecordTopService testRecordTopService;
    private final TestRecordAllService testRecordAllService;
    private final ProduceOrderLogService produceOrderLogService;

    public TcpMsgInHandler(ProduceOrderService produceOrderService, TestRecordTopService testRecordTopService,
                           TestRecordAllService testRecordAllService,ProduceOrderLogService produceOrderLogService) {
        this.produceOrderService = produceOrderService;
        this.testRecordTopService = testRecordTopService;
        this.testRecordAllService = testRecordAllService;
        this.produceOrderLogService = produceOrderLogService;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("client active: {}", ctx.channel().remoteAddress());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("client inactive: {}", ctx.channel().remoteAddress());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf byteBuf = (ByteBuf) msg;
        String readMsg = byteBuf.toString(CharsetUtil.UTF_8);
        ProduceMsg produceMsg = null;
        try {
            produceMsg = JSONObject.parseObject(readMsg, ProduceMsg.class);
        } catch (Exception e) {
            log.error("ProduceMsg 格式化消息失败!{}", e.getMessage());
            ctx.write(ERROR_FORMAT_MSG);
        }

        if (produceMsg != null) {
            log.info("Client Msg: {}", produceMsg);
            TestRecordTopVO testRecordTopVO;
            String msgType = produceMsg.getMsgType();
            String msgContent = produceMsg.getMsgContent();
            switch (msgType) {
                // 通过IMEI号获取订单信息
                case FIND_PRODUCE_ORDER_INFO:
                    ProduceOrderVO produceOrderVO = produceOrderService.queryProduceOrder(msgContent);
                    if (produceOrderVO == null) {
                        ctx.write(ERROR_RECORD_NOT_EXIST);
                    } else {
                        ctx.write(JSONObject.toJSONString(produceOrderVO));
                    }
                    break;
                case SAVE_PRODUCE_DATA:

                    break;
                case SAVE_PRODUCE_LOG:
                    
                    break;
                case PRODUCT_OUTBOUND:

                    break;
                case GET_METER_CODE:

                    break;
                case FIND_PRODUCE_RECORD_BY_IMEI:
  
                    break;
                case FIND_PRODUCE_RECORD_BY_METER_CODE:

                    break;
                default:
                    log.error("消息不存在!");
            }
        }

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("client {} exception: {}", ctx.channel().remoteAddress(), cause);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值