Netty初步——搭建一个Netty程序

    Netty是一款用于快速开发高性能的网络应用程序的Java框架,是一个异步事件驱动的网络应用框架。

导入依赖


            io.netty
          netty-all
            4.1.5.Final
        

        
            junit
            junit
            4.10
            test
        

创建一个Netty程序

1. ClientHandle
public class ClientHandle extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext channelHandlerContext) throws Exception {
        System.out.println("客户端已激活");
        channelHandlerContext.writeAndFlush("Hello world");
    }

    @Override
    public void channelInactive(ChannelHandlerContext channelHandlerContext) throws Exception {
        System.out.println("客户端已关闭");
    }

    @Override
    public void channelRead(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
        System.out.println("发送消息");

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable throwable) throws Exception {
        throwable.printStackTrace();
        channelHandlerContext.channel().close();
    }

}
2. Client
public class Client {
    private int port;
    private String ip;

    public Client(int port,String ip){
        this.port=port;
        this.ip=ip;
    }

    public void start(){
        EventLoopGroup eventExecutors=new NioEventLoopGroup();
        Bootstrap bootstrap=new Bootstrap();
        bootstrap.group(eventExecutors)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline channelPipeline=socketChannel.pipeline();
                        channelPipeline.addLast("decoder", new StringDecoder());
                        channelPipeline.addLast("encoder", new StringEncoder());
                        channelPipeline.addLast(new ClientHandle());
                    }
                });
        try {
            ChannelFuture channelFuture=bootstrap.connect("127.0.0.1",9999).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
3. ServerHandle
public class ServerHandle extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext channelHandlerContext) throws Exception {
        System.out.println("服务端已激活");
    }

    @Override
    public void channelInactive(ChannelHandlerContext channelHandlerContext) throws Exception {
        System.out.println("服务端已关闭");
    }

    @Override
    public void channelRead(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
        System.out.println("接收到从客户端"+channelHandlerContext.channel().remoteAddress()+"的消息:"+o.toString());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable throwable) throws Exception {
        throwable.printStackTrace();
        channelHandlerContext.channel().close();
    }
}
4. Server
public class Server {
    private int port;
    //private String ip;

    public Server(int port){
       // this.ip=ip;
        this.port=port;
    }

    public void start(){
        EventLoopGroup listerloopGroup=new NioEventLoopGroup();
        EventLoopGroup workLoopGroup=new NioEventLoopGroup();
        ServerBootstrap serverBootstrap=new ServerBootstrap();
        serverBootstrap.group(listerloopGroup,workLoopGroup)
                .channel(NioServerSocketChannel.class)
                .localAddress(port)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline channelPipeline=socketChannel.pipeline();
                        channelPipeline.addLast("decoder", new StringDecoder());
                        channelPipeline.addLast("encoder", new StringEncoder());
                        channelPipeline.addLast(new ServerHandle());
                    }
                });
        try {
            ChannelFuture channelFuture=serverBootstrap.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

上述程序表示了客户端连到服务端时,客户端向服务端发送一条Hello world的信息。

组件初解

  • EventLoopGroup、EventLoop、Channel
  1. EventLoopGroup为Netty的事件循环组,里面包含了多个EventLoop,服务端一般具有两个事件循环组,一个用于监听新的连接,另外一个来处理已连接的客户端,当然也可以使用一个,那么这两者都在一个事件循环组里进行。

  2. 每个EventLoop代表着一个线程,用来处理其绑定的Channel的所有事件,且每个EventLoop可以被绑定多个Channel。

  • ChannelHandlr、ChannelPipline、ChannelHandleContext
  1. 每个Channel都有一条ChannelPipline,每个ChannelPipline里面包括多个ChannelHandle(至少一个)
  2. ChannelHandle用来处理流经Channel的数据,通过ChannelHandleContext将每个ChannelHandle处理的结果连接起来
  • ChannelInboundHandlerAdapter、ChannelOutboundHandlerAdapter
  1. ChannelInboundHandlerAdapter对应着入站事件(读事件、注册事件等),相反ChannelOutboundHandlerAdapter对应着出站事件(写事件等)
  2. 这两者是相对的概念,对服务器来言,服务端写入客户端称之为出站,而对于客户端来言,客户端写入服务器称为出站
  • ServerBootstrap、Bootstrap
  1. ServerBootstrap对应服务端的启动类,而Bootstrap对应着客户端的启动类
  2. 大部分的配置都在启动类上进行的,包括指明传输方式、配置ChannelHandle等
  • childHandler方法、Handle方法
  1. childHandler方法为已被接受的子Channel处理,代表着一个绑定到远程节点的套接字,也就是为每个客户端设置ChannelHandle,用来处理每个客户端除了连接的操作
  2. Handle方法添加的ChannelHandle由ServerChannel处理,代表着为服务端创建新的子Channel并处理,其实就是处理新的客户端连接

注意事项

  1. 传输时必须对消息进行利用解码器与编码器进行编码和解码,否则传输的消息接收不到
  2. 服务端与客户端指定的传输方式必须一致,即服务端指定传输方式为NIO,则客户端也必须使用NIO

你可能感兴趣的:(Netty)