Not faster than NIO (epoll) on unix systems (which is true) There is no daragram suppport Unnecessary threading model (too much abstraction without usage) 以上就是Netty目前还是使用NIO的方式的原因;
BootStrap: 是Netty框架的启动类和主入口类,分为客户端BootStrap和服务器类ServerBootStrap两种。 Channel:是Java NIO 的一个基本构造 EventLoop:可以看成一个线程,EventLoopGroup可以看成是线程组。
事件和ChannelHandler、ChannelPipeline Netty 使用不同的事件来通知我们状态的改变或者是操作的状态。这使我们能够基于已经发生的事件来触发适当的动作。 每个事件都可以被分发给 ChannelHandler 类中的某个用户实现的方法,既然事件分为入站和出站,用来处理事件的 ChannelHandler 也被分为可以处理入站事件的 Handler 和出站事件的 Handler,当然有些 Handler 既可以处理入站也可以处理出站。 这些ChannelHandler都放在ChannelPipeline中统一管理,事件就会在ChannelPipeline中流动,并被其中一个或多个ChannelHandler处理。
ChannelFuture Netty中所有的 I/O操作都是异步的,我们知道“异步不需要主动等待结果的返回,而是通过其他方式,状态通知”。 JDK 预置了 interface java.util.concurrent.Future, Future 提供了一种在操作完成时通知应用程序的方式。它将在未来某个时刻完成,并提供对其结果的访问,但是其过程繁琐,会进行阻塞。于是Netty提供了他自己的实现ChannelFuture,用于异步操作的时候使用。
代码演示 1.先提供一个service
private static Logger logger = LoggerFactory.getLogger(EchoServer.class);
private final int port;
public EchoServer(int port){
this.port = port;
}
public static void main(String[] args) throws Exception{
int port = 9999;
EchoServer echoServer = new EchoServer(port);
logger.info("服务器即将启动");
echoServer.start();
logger.info("服务器关闭");
}
public void start() throws Exception{
EchoServerHandler serverHandler = new EchoServerHandler();
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(serverHandler);
}
});
ChannelFuture future = bootstrap.bind().sync();
future.channel().closeFuture().sync();
}finally {
group.shutdownGracefully().sync();
}
}
2.再实现service的Handler
@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf)msg;
System.out.println("Server accept: "+in.toString(CharsetUtil.UTF_8));
ctx.writeAndFlush(in);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
3.实现Client
private final int port;
private final String host;
public EchoClient(int port,String host){
this.host = host;
this.port = port;
}
public void start() throws InterruptedException{
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host,port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture future = bootstrap.connect().sync();
future.channel().closeFuture().sync();
}finally {
group.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws InterruptedException{
new EchoClient(9999,"127.0.0.1").start();
}
4.实现client的Handler
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
System.out.println("client Accept"+byteBuf.toString(CharsetUtil.UTF_8));
channelHandlerContext.close();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer(
"Hello,Netty",CharsetUtil.UTF_8));
}
}
运行演示
|