package cn.org.hentai.jtt1078.app; import cn.org.hentai.jtt1078.server.video.Jtt1078Handler; import cn.org.hentai.jtt1078.server.video.Jtt1078MessageDecoder; 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 lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PreDestroy; @Slf4j @Component public class VideoServer { private ServerBootstrap serverBootstrap; private EventLoopGroup bossGroup; private EventLoopGroup workerGroup; @Value("${jt1078.video.port}") private int port; @PreDestroy public void destroy() { shutdown(); } public void start() throws Exception { serverBootstrap = new ServerBootstrap(); serverBootstrap.option(ChannelOption.SO_BACKLOG, 102400); bossGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors()); workerGroup = new NioEventLoopGroup(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(final SocketChannel channel) { ChannelPipeline p = channel.pipeline(); p.addLast(new Jtt1078MessageDecoder()); p.addLast(new Jtt1078Handler()); } }); Channel ch = serverBootstrap.bind("0.0.0.0", port).sync().channel(); log.info("🎥 Video Server started on port {}", port); // 不要 ch.closeFuture().sync(),会阻塞 } public void shutdown() { try { if (bossGroup != null) bossGroup.shutdownGracefully(); if (workerGroup != null) workerGroup.shutdownGracefully(); } catch (Exception e) { e.printStackTrace(); } } }