netty是一个提供异步事件驱动的网络应用程序框架和工具,用以快速开发高性能高可靠性的服务器和客户端程序。预计现在的项目马上要升级为分布式模式,所以打算学习下netty,看看该框架是否可以给项目带来好处。
跟学习很多框架一样,首先跑通一个hello world程序,代码的功能很简单,首先启动服务器端程序,然后启动的客户端程序,服务器接受客户端连接,返回字符串“hello, netty中午呢”,客户端打印返回的字符串,然后关闭连接。
服务器端代码:
public class HelloServer {
public void run() throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new HelloServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(7777).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new HelloServer().run();
}
}
public class HelloServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(final ChannelHandlerContext ctx) throws Exception {
char[] msg = "hello, netty中午呢".toCharArray();
final ByteBuf buf = ctx.alloc().buffer(msg.length);
for (char c : msg) {
buf.writeChar(c);
}
final ChannelFuture f = ctx.writeAndFlush(buf);
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
assert f == future;
ctx.close();
}
});
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//打印异常信息并关闭连接
cause.printStackTrace();
ctx.close();
}
}
客户端代码:
public class HelloClient {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new HelloClientHandler());
}
});
ChannelFuture f = b.connect("127.0.0.1", 7777).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
}
public class HelloClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
while (buf.isReadable()) {
System.out.print(buf.readChar());
System.out.flush();
}
buf.release();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}