spring boot 集成netty,及其一些基本概念
一、基本概念
1、channel:通道,入站或者出站数据的载体
2、ChannelHandler:通道处理器,业务逻辑写在这里面,netty 5版本将入战和出站合并成了ChannelHandler
3、ChannelPipeline:通道里的管道,是一个或者多个ChannelHandler链的容器,当channel被创建时,会为该Channel自动分配一个ChannelPipeline,ChannelPipeline中可以放多个ChannelHandler。
4、ChannelHandlerContext:通道处理器上下文,代表了ChannelHandler和ChannelPipeline的关联关系,每当有ChannelHandler被添加到ChannelPipeline时就会创建一个ChannelHandlerContext。ChannelHandlerContext的主要功能是管理它所关联的ChannelHandler和在同一个ChannelPipeline中其他的ChannelHandler之间的交互。
5、ChannelHandlerAdapter:通道处理器的适配器,提供了入站和出站ChannelHandler的基本实现。
6、EventLoop与EventLoopGroup:称为事件循环,用来运行连着周期内发生的事件的。EventLoopGroup为每个新创建的Channel分配一个EventLoop。多个Channel可以共享一个EventLoop。
7、SimpleChannelInboundHandler:可以用来接收解码消息,无需手动释放资源。
8、引导:作用是创建Channel组装成可运行的程序。分为客户端引导和服务端引导。客户端引导:为客户端应用程序创建Channel当调用bind()或者connect()方法时就会创建一个Channel。服务器引导:当bind()方法被调用时会创建一个ServerChannel,当有客户端连接并且服务器端接受时,ServerChannel会创建相应的Channel进行通信。
9、ChannelInitializer:通道Channel初始化时调用。
10、入站和出站:入站是指数据从网络层流向你的应用程序,出战是指数据从应用程序流向网络层。在ChannelPipeline的流向,入站是从头到尾,出站是从尾流向头部。
11、注意:ChannelHandler的实现类,如果被标记为@Sharable,则代码该处理器可以被添加到多个ChannelPipeline中去。
二、搭建一个简单的客户端和服务端
1、安装依赖
io.netty netty-all 5.0.0.Alpha2
2、客户端
2.1 新建处理器类:EchoClientHandler
@ChannelHandler.Sharablepublic class EchoClientHandler extends SimpleChannelInboundHandler { @Override public void channelActive(ChannelHandlerContext ctx){ ctx.writeAndFlush(Unpooled.copiedBuffer(\"Netty rocks!\", CharsetUtil.UTF_8)); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf in = (ByteBuf) msg; System.out.println(\"Client received: \" + in.toString(CharsetUtil.UTF_8)); } @Override protected void messageReceived(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){ cause.printStackTrace(); ctx.close(); }}
2.2 新建客户端引导
public class EchoClient { private final String host; private final int port; public EchoClient(String host, int port) { this.host = host; this.port = port; } public void start() throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .remoteAddress(new InetSocketAddress(host, port)) .handler(new ChannelInitializer() { @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 Exception { new EchoClient(\"127.0.0.1\", 2221).start(); }}
3、服务器端
3.1 新建服务器端ChannelHandler
@ChannelHandler.Sharable//@ChannelHandler.Sharablepublic class EchoServerHandler extends SimpleChannelInboundHandler { @Override public void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf in = (ByteBuf) msg; System.out.println(\"Server received: \" + in.toString(CharsetUtil.UTF_8)); ctx.write(in); } @Override public void channelReadComplete(ChannelHandlerContext ctx){ ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) .addListener(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){ cause.printStackTrace(); ctx.close(); } @Override protected void messageReceived(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { }}
3.2 新建服务器端引导
public class EchoServer { private final int port; public EchoServer(int port) { this.port = port; } public void start() throws Exception { final EchoServerHandler serverHandler = new EchoServerHandler(); EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(group) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(serverHandler); } }); System.out.println(\"监听端口\"); ChannelFuture f=b.bind().sync(); System.out.println(\"服务端关闭\"); f.channel().closeFuture().sync(); }finally { group.shutdownGracefully().sync(); } } public static void main(String[] args) throws Exception { new EchoServer(2221).start(); }}