SpringBoot Netty构建的初始化bean的方式

@Data
public class NettyConfig implements Serializable {

	private static final long serialVersionUID = 6620106410814342128L;

	private static final int processors = NettyRuntime.availableProcessors();

	public Boolean enable = false;// 是否开启
	public Boolean isTcp = true;// 是否TCP
	public String name = "Netty";// 服务名称
	public Integer port = 11111;// 端口号

	public Integer workerCore = processors + 2;;
	public Integer businessCore = Math.max(1, processors >> 1);
	public Integer readerIdleTime = 240;
	public Integer writerIdleTime = 0;
	public Integer allIdleTime = 0;
	//标识位[2] + 消息头[21] + 消息体[1023 * 2(转义预留)]  + 校验码[1] + 标识位[2]
	public Integer maxFrameLength = 2 + 21 + 1023 * 2 + 1 + 2;
	
	// netty Session管理
	public SessionManager sessionManager;
	// netty Channel处理列表
	public ChannelHandler hander;;
}
@Slf4j
public abstract class NettyServer {

	protected boolean isRunning;
	protected NettyConfig config;
	protected EventLoopGroup bossGroup;
	protected EventLoopGroup workerGroup;
	protected EventExecutorGroup businessGroup;

	protected NettyServer(NettyConfig config) {
		this.config = config;
	}
	
	protected AbstractBootstrap<?, ?> initializeTCP() {
		bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory(config.name, Thread.MAX_PRIORITY));
		workerGroup = new NioEventLoopGroup(config.workerCore, new DefaultThreadFactory(config.name, Thread.MAX_PRIORITY));
		if (config.businessCore > 0) {
			businessGroup = new DefaultEventExecutorGroup(config.businessCore);
		}
		ServerBootstrap serverBootstrap = new ServerBootstrap();
		serverBootstrap.group(bossGroup, workerGroup)
				.channel(NioServerSocketChannel.class)
				.childOption(ChannelOption.SO_REUSEADDR, true)
				.option(ChannelOption.SO_BACKLOG, 1024)
				.childOption(NioChannelOption.TCP_NODELAY, true)
				.childHandler(config.hander);
		 //内存泄漏检测 开发推荐PARANOID 线上SIMPLE
        ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.SIMPLE);
		return serverBootstrap;
	}
	
	protected AbstractBootstrap<?, ?> initializeUDP() {
		bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory(config.name, Thread.MAX_PRIORITY));
		if (config.businessCore > 0)
			businessGroup = new DefaultEventExecutorGroup(config.businessCore);
		return new Bootstrap()
				.group(bossGroup).channel(NioDatagramChannel.class)
				.option(NioChannelOption.SO_REUSEADDR, true)
				.option(NioChannelOption.SO_RCVBUF, 1024 * 1024 * 50)
				.handler(config.hander);
	}

	public synchronized boolean start() {
		if (!config.enable) {
			return false;
		}
		if (isRunning) {
			log.info("======{}已经启动,port:{}======", config.name, config.port);
			return isRunning;
		}
		AbstractBootstrap<?, ?> bootstrap = config.isTcp ? initializeTCP() : initializeUDP();
		ChannelFuture future = bootstrap.bind(config.port).awaitUninterruptibly();
		future.channel().closeFuture().addListener(f -> {
			if (isRunning)
				stop();
		});
		if (future.cause() != null)
			log.error("===启动失败===", future.cause());
		if (isRunning = future.isSuccess())
			log.info("\n\n\t\t\t\t\t\t\t\t======{}启动成功,port:{}======\n", config.name, config.port);
		return isRunning;
	}

	public synchronized void stop() {
		if (!config.enable) {
			return;
		}
		isRunning = false;
		try {
			Future<?> future = this.workerGroup.shutdownGracefully().await();
			if (!future.isSuccess()) {
				log.error("workerGroup 无法正常停止:{}", future.cause());
			}
			future = this.bossGroup.shutdownGracefully().await();
			if (!future.isSuccess()) {
				log.error("bossGroup 无法正常停止:{}", future.cause());
			}
			future = this.businessGroup.shutdownGracefully().await();
			if (!future.isSuccess()) {
				log.error("businessGroup 无法正常停止:{}", future.cause());
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		log.info("\n\n\t\t\t\t\t\t\t\t======{} 已经停止,port:{}======\n", config.name, config.port);
	}
}
@Configuration
public class Netty808Server extends NettyServer {

	@Resource
	private Netty808Config config;

	@Resource
	private TCPListenHandler tcpListenHandler;

	@Resource
	private JT808DecoderHandler jt808DecoderHandler;

	@Resource
	private JT808ByteToEntityHandler jt808ByteToEntityHandler;
	
	@Resource
	private JT808EntityToByteHandler jt808EntityToByteHandler;
	
	@Resource
	private JT808EncoderHander jt808EncoderHander;
	
	@Resource
	private JT808DispatcherHandler jt808DispatcherHandler;

	protected Netty808Server(Netty808Config config) {
		super(config);
	}

	@Bean(name = "JT808", initMethod = "start", destroyMethod = "stop")
	public NettyServer run() {
		config.setHander(new ChannelInitializer<NioSocketChannel>() {
			@Override
			public void initChannel(NioSocketChannel ch) throws Exception {
				ch.pipeline().addLast(new IdleStateHandler(config.readerIdleTime, config.writerIdleTime, config.allIdleTime));// 心跳
				ch.pipeline().addLast(new DelimiterBasedFrameDecoder(config.maxFrameLength, new Delimiter(new byte[] { 0x7e }, true)));
				ch.pipeline().addLast(tcpListenHandler);// 监听器
				
				//入栈
				ch.pipeline().addLast(jt808DecoderHandler);// 转义 BCC
				ch.pipeline().addLast(jt808ByteToEntityHandler);// 报文-实体
				
				//出栈
				ch.pipeline().addLast(jt808EncoderHander);//BCC 反转义
				ch.pipeline().addLast(jt808EntityToByteHandler);//实体-报文
				
				// 业务分发是入站最后一个处理器, 出站第一个处理器, 位置要放在最后
				ch.pipeline().addLast(businessGroup, jt808DispatcherHandler);//业务分发 这里使用业务线程组
			}
		});
		return new Netty808Server(config);
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NuoleAQ

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值