Netty(一)簡単なEcho Server&Cientを作成します。
13546 ワード
Netty概要
Nettyのコアコンポーネント: Chanel コール Future 事件とChanelHandler ChanelChannelは、着信(入局)またはデータの流れを伝えるキャリアと見なし、オンまたはオフ、接続または切断され得る。
一つのコールバックは実は一つの方法であり、もう一つの方法に提供された方法の参照を指す。これにより、コールバックを受ける方法は、適切なときに前者を呼び出すことができる。1つのコールバックがトリガされると、関連するイベントは、1つのinterface-ConnelHandlerの実装によって処理され得る。
FutureFutureは、動作完了時にアプリケーションに通知する他の方法を提供しています。このオブジェクトは非同期動作の結果のプレースホルダとして考えられ、将来のある時点で完了し、その結果に対するアクセスを提供します。ChanelFutureは、1つまたは複数のChanelFutureListenerのインスタンスを登録することができるように、追加のいくつかの方法を提供している。ChanelFutureListenerの例によって提供される通知機構は、対応する動作が完了したかどうかを手動で確認する必要がなくなる。
イベントとChanelHandlerNettyは、異なるイベントを使用して、状態の変更または操作の状態を知らせてくれます。これにより、発生したイベントに基づいて適切な動作をトリガすることができる。各イベントは、ChanelHandlerクラスのあるユーザに配信されて実現される方法である。
Mavenを創建するプロジェクト
プロジェクト全体のディレクトリ構造は以下の通りです。
echo-parentのpomファイル
EchoServer
EchoServer Handler
EchoServer EchoServer Handlerは、業務ロジック を実現しました。 main()方法はサーバをガイドしました。 ガイドプロセスは以下の通りです。は、サーバをガイドおよびバインディングするためのServer Boostrapの例を作成する。 は、NioEventLoopGroupの例を作成し、割り当てて、新規の接続および読み書きなどのイベントの処理を行う。 は、サーバがローカルのInetSocketAddressをバインドすることを指定する。 は、EchoServer Handlerの例を使用して、新しいChannelを初期化する。 は、サーバをバインディングするためにServer Bootstrap.bind()方法を起動する。 エチョーク
Echoクライアント:はサーバに接続されている。 は、1つまたは複数のメッセージを送信する。 は、各メッセージについて、サーバから返される同じメッセージを待ち、受信する。 接続を閉じる Echocolient Handlerは、クライアントを初期化するために、Bootstrapの例を作成する。 は、イベント処理を行うためにNioEventLoopGroupの例を割り当て、イベント処理は、新たな接続を作成することと、入局および出局データを処理することとを含む。 は、サーバ接続のためのInetSocketAddressの例を作成する。 接続が確立されると、Echocolient Handlerの例がChannelのChanelPipelineにインストールされます。 すべての設定が完了したら、Bootstrap.co nnect()方法を呼び出してリモートノードに接続する。 テストを実行
echo-parentディレクトリに入って実行します。
Nettyのコアコンポーネント:
一つのコールバックは実は一つの方法であり、もう一つの方法に提供された方法の参照を指す。これにより、コールバックを受ける方法は、適切なときに前者を呼び出すことができる。1つのコールバックがトリガされると、関連するイベントは、1つのinterface-ConnelHandlerの実装によって処理され得る。
FutureFutureは、動作完了時にアプリケーションに通知する他の方法を提供しています。このオブジェクトは非同期動作の結果のプレースホルダとして考えられ、将来のある時点で完了し、その結果に対するアクセスを提供します。ChanelFutureは、1つまたは複数のChanelFutureListenerのインスタンスを登録することができるように、追加のいくつかの方法を提供している。ChanelFutureListenerの例によって提供される通知機構は、対応する動作が完了したかどうかを手動で確認する必要がなくなる。
イベントとChanelHandlerNettyは、異なるイベントを使用して、状態の変更または操作の状態を知らせてくれます。これにより、発生したイベントに基づいて適切な動作をトリガすることができる。各イベントは、ChanelHandlerクラスのあるユーザに配信されて実現される方法である。
Mavenを創建するプロジェクト
プロジェクト全体のディレクトリ構造は以下の通りです。
echo-parentのpomファイル
4.0.0
com.nasuf.echo
echo-parent
pom
1.0-SNAPSHOT
../echo-client
../echo-server
localhost
9999
io.netty
netty-all
4.1.10.Final
compile
maven-compiler-plugin
maven-failsafe-plugin
maven-surefire-plugin
org.codehaus.mojo
exec-maven-plugin
echo-serverのpomファイル
echo-parent
com.nasuf.echo
1.0-SNAPSHOT
../echo-parent/pom.xml
4.0.0
echo-server
org.codehaus.mojo
exec-maven-plugin
run-server
java
com.echo.server.handler.EchoServer
${echo-server.port}
echo-clientのpomファイル
echo-parent
com.nasuf.echo
1.0-SNAPSHOT
../echo-parent/pom.xml
4.0.0
echo-client
org.codehaus.mojo
exec-maven-plugin
run-server
java
com.echo.client.handler.EchoClient
${echo-server.hostname}
${echo-server.port}
そして、echo-clientとecho-serverを構築します。EchoServer
EchoServer Handler
package com.echo.server.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
// @Sharable ChannelHandler Channel
@Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.println(
"Server received: " + in.toString(CharsetUtil.UTF_8));
// , ,
ctx.write(in);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// , Channel
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
未決メッセージとは、現在ChanelOutboundBufferに一時的に保存されているメッセージで、次のflash()またはwriteAndFlash()メソッドを呼び出したときにソケットに書き込もうとするものです。EchoServer
package com.echo.server.handler;
import java.net.InetSocketAddress;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
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
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(serverHandler);
}
});
// , 。 sync() Thread ,
ChannelFuture f = b.bind().sync();
// sync() , , Channel
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println(
"Usage: " + EchoServer.class.getSimpleName() + " "
);
return;
}
int port = Integer.parseInt(args[0]);
new EchoServer(port).start();
}
}
まとめ:Echoクライアント:
package com.echo.client.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
@Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
エチョークpackage com.echo.client.handler;
import java.net.InetSocketAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
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 EchoClient {
private final String host;
private final int port;
public EchoClient(String host, int port) {
this.host = host;
this.port = port;
}
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println(
"Usage: " + EchoClient.class.getSimpleName() +
" ");
return;
}
String host = args[0];
int port = Integer.parseInt(args[1]);
new EchoClient(host, port).start();
}
public void start() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.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 f = b.connect().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
}
まとめ:echo-parentディレクトリに入って実行します。
mvn clean package
その後、それぞれサービス端末とクライアントで実行される:mvn exec:java
サービス先で見られます。$ mvn exec:java
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building echo-server 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ echo-server ---
クライアントで見ました:$ mvn exec:java
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building echo-client 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ echo-client ---
Client received: Netty rocks!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.903 s
[INFO] Finished at: 2018-11-18T20:54:08+08:00
[INFO] Final Memory: 11M/309M
[INFO] ------------------------------------------------------------------------
クライアントの実行が完了し、終了しました。サービスカウンターのウィンドウに戻ると、次のような情報が見られます。Server received: Netty rocks!
『Netty実戦』第二章