从原生的Java NIO api过度到netty,这个过程应该还是比较平滑的。毕竟原生api出了名的难用,据说还有bug。
下面是学习netty过程中的一些代码和笔记,大部分代码都来自于官方文档。
官网文档地址
https://netty.io/wiki/user-guide-for-4.x.html
netty依赖
<!-- netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.63.Final</version>
</dependency>
编写第一个demo,实现一个需求。服务端可以接收所有的请求,但是除了打印字符串外不做任何处理。
public class DiscardServer {
private int port;
public DiscardServer(int port) {
this.port = port;
}
public static void main(String[] args) throws Exception {
int port = 8080;
if(args.length > 0) {
port = Integer.parseInt(args[0]);
}
new DiscardServer(port).run();
}
public void run() throws Exception {
//用于接收连接
EventLoopGroup bossGroup = new NioEventLoopGroup();
//建立连接后,交给worker处理
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
//初始化初始化一个新的channel用于接受连接
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new DiscardServerHandler());
}
})
//为NioServerSocketChannel设置一些选项 (parent)
.option(ChannelOption.SO_BACKLOG, 128)
//为SocketChannel设置选项 (child)
.childOption(ChannelOption.SO_KEEPALIVE, true);
//绑定端口、接收连接
ChannelFuture f = b.bind(port).sync();
//关闭服务。直到服务端的socket关闭,才会执行到这,本demo并不会执行到这一步
f.channel().closeFuture().sync();
}finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
DiscardServerHandler
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) {
System.out.print((char) in.readByte());
//flush让io立刻执行,并清空缓存
System.out.flush();
}
}finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
telnet测试
telnet localhost 8080
ctrl + ]
send hello, world
控制台打印