6. Netty 中的 NIO 应用

6. Netty 中的 NIO 应用

  • 6.1. Netty 中的 NIO 模型分析


Netty 是一个基于 NIO 技术的网络编程框架,底层实现了对 java 中 NIO API的封装。它基于异步事件驱动,可以快速开发高性能网络应用程序,并在可维护性方面有很好的表现

Netty 的健壮性、功能、性能、可定制性和可扩展性在同类框架中都首屈一指,它已经得到成百上千的商用项目验证,当然这些都离不开它背后的 NIO 技术,线程技术的合理应用。

  • 6.2. Netty 中的 NIO 案例分析


基于一个时间服务器对象与时间客户端对象的通讯为案例,分析一下netty 中 NIO 的应用.
本项目采用的 netty 为 4.x 的版本,例如

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.16.Final</version>
</dependency>
  • 6.2.1. Netty 服务端入门实现


1. 服务端创建关键步骤

  • 1) 创建服务端启动类对象(ServerBootstrap)
  • 2) 设置线程组(Boss 线程组和 Worker 线程组)
  • 3) 设置服务端 channel 对象(NioServerSocketChannel)
  • 4) 设置 ChanelHandler 对象
  • 5) 绑定并启动端口监听(等待客户端链接)

2. 服务端代码实现

创建事件服务器:

public class TimeServer {
    public void start() throws Exception{
        NioEventLoopGroup bossGroup=new NioEventLoopGroup();
        EventLoopGroup workerGroup=new NioEventLoopGroup();
        try {
            ServerBootstrap b=new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new TimeServerHandler());
                        };
                    })
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture f=b.bind(9999).sync();
            f.channel().closeFuture().sync();
        }finally{
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    public static void main(String[] args)throws Exception {
        new TimeServer().start();
    }
}

创建服务端时间处理器:

public class TimeServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(final ChannelHandlerContext ctx)
            throws Exception {
        final ByteBuf time=ctx.alloc().buffer(8);
        time.writeLong(System.currentTimeMillis());
        final ChannelFuture f=ctx.writeAndFlush(time);
        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)
    {
        cause.printStackTrace();
        ctx.close();
    }
}
  • 6.2.2. Netty 客户端入门实现


1. 客户端创建关键步骤

  • 1) 创建客户端启动类对象(Bootstrap)
  • 2) 设置线程组(Worker 线程组)
  • 3) 设置客户端 channel 对象(NioSocketChannel)
  • 4) 设置 ChanelHandler 对象
  • 5) 连接服务端

2. 客户端代码实现

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class TimeClient {
    public void connect(String ip, Integer port) throws Exception {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //Bootstrap客户端用于简单建立Channel
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            //NioSocketChannel用于客户端创建Channel
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    //指定使用的数据处理方式
                    ch.pipeline().addLast(new TimeClientHandler());
                }

                ;
            });
            //客户端开始连接
            ChannelFuture f = b.connect(ip, port).sync();
            //等待直到这个连接被关闭
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new TimeClient().connect("127.0.0.1", 9999);
    }
}

创建客户端时间处理器:

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Date;

public class TimeClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        ByteBuf m=(ByteBuf)msg;
        try {
            long currentTimeMillis = m.readLong();
            System.out.println("from server:"+new Date(currentTimeMillis));
            ctx.close();
        } finally {
            m.release();
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值