最終更新日:180909 原本2018/06/10 

Nettyを使ってクライアントを実装してみた

初めに

前回はNettyを使ってサーバーを作りましたが、今日は引き続きクライアント側も実装してみます。

実装

➀アクセスの生成や終了などの処理

public class EchoClient {
    private final String host;
    private final int port;

    public EchoClient() {
        this(0);
    }

    public EchoClient(int port) {
        this("localhost", port);
    }

    public EchoClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress(this.host, this.port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            System.out.println("connected...");
                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            System.out.println("created..");

            ChannelFuture cf = b.connect().sync();
            System.out.println("connected...");

            cf.channel().closeFuture().sync();
            System.out.println("closed..");
        } finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws Exception {
        new EchoClient("127.0.0.1", 31535).start();
    }
}

②タイミングによるを起動された関数(callbackはず)

  • channelActive() - サーバーへの接続がクリエイトされた時
  • channelRead0() - サーバー側がデータを貰った時
  • exceptionCaught() - レラーが感知された時
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client channelActive..");
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        System.out.println("client channelRead..");
        ByteBuf buf = msg.readBytes(msg.readableBytes());
        System.out.println("Client received:" + ByteBufUtil.hexDump(buf) + "; The value is:" + buf.toString(Charset.forName("utf-8")));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

}

結果認証

サーバーを起動し、接続を待ち受け中

class EchoServer started and listen on /0:0:0:0:0:0:0:0:31535

サーバーを起動し、サーバーにリクエストします
クライアントとサーバーそれぞれの出力は以下になります

  • クライアント
created..
connected...
client channelActive..
connected...
client channelRead..
Client received:4e6574747920726f636b7321; The value is:Netty rocks!
closed..

Process finished with exit code 0
  • サーバー
class EchoServer started and listen on /0:0:0:0:0:0:0:0:31535
connected...; Client:/127.0.0.1:56967
server channelRead...; received:PooledUnsafeDirectByteBuf(ridx: 0, widx: 12, cap: 1024)
server channelReadComplete..

まとめ

今回はNettyを使ってNIOの転送路を作ってみました、ServerSocketChannelやSocketChannelなのに比べて、低レベルのAPIを書く必要がなく、楽になりました。