最近在做netty与硬件对接的一个项目。在网上搜了好多springboot启动netty的方式,好像都不行,有一个实现 CommandLineRunner接口的方式,在本地测试,springboot内置的tomcat和netty都可以启动。
但一放到服务器上,tomcat还是无法启动。自己思来想去找不到问题所在。
后面在 这个帖子上添加链接描述
看到了这样一句话:感觉像是 netty 绑定端口的时候阻塞了主线程,导致 springboot 到达不了启动 tomcat 内置容器的那一步。
我一想很有可能啊,然后另开了一个线程来启动netty,果然就没问题了。
下面是实现代码:
@EnableCaching
@SpringBootApplication
@EnableConfigurationProperties
@EnableTransactionManagement
@EnableAutoConfiguration
@MapperScan({"com.tyzn.mapper","com.tyzn.iot.dao"})
public class Application implements CommandLineRunner {
@Autowired
private NettyServer nettyServer;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
//InetSocketAddress address = new InetSocketAddress(port);
new Thread(nettyServer).start();
}
}
@Slf4j
@Component
public class NettyServer implements Runnable{
public void start(InetSocketAddress address) {
//配置服务端的NIO线程组
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(10);
try {
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup) // 绑定线程池
.channel(NioServerSocketChannel.class)
.localAddress(address)
.childHandler(new NettyServerChannelInitializer())//编码解码
.option(ChannelOption.SO_BACKLOG, 128) //服务端接受连接的队列长度,如果队列已满,客户端连接将被拒绝
.childOption(ChannelOption.SO_KEEPALIVE, true); //保持长连接,2小时无数据激活心跳机制
// 绑定端口,开始接收进来的连接
ChannelFuture future = bootstrap.bind(address).sync();
log.info("netty服务器开始监听端口:" + address.getPort());
//关闭channel和块,直到它被关闭
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
@Value("${tyzn.port}")
private int port;
@Override
public void run() {
InetSocketAddress address = new InetSocketAddress(port);
this.start(address);
}
}
这样就可以了!
后面还会把netty与硬件对接,传输16进制报文,整理一下吧。