注意点
- Nettyは現在、3.x版と4.x/5.x版に分けられています。これは、4.xと5.xのAPIがほぼ同じであるにもかかわらず、3.xと4.x/5.xのバージョン間でAPIが大きく変化したためです。
- Nettyは分布式プロセス通信やゲームサーバ開発などで広く利用されています。例えば、Hadoop、Dubbo、Akkaなどの分散機能を持つフレームワークの底层RPC通信は、Nettyに基づいています。これらのフレームワークが使用しているバージョンは、多くの場合Netty 3.xを使用しています。
- `SimpleChannelHandler`はメッセージの受信と送信を処理します。
1. サーバーコード
package com.example.netty.lesson2;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NettyServer {
public static void main(String[] args) {
ServerBootstrap bootstrap = new ServerBootstrap();
ExecutorService boss = Executors.newCachedThreadPool();
ExecutorService work = Executors.newCachedThreadPool();
bootstrap.setFactory(new NioServerSocketChannelFactory(boss, work));
bootstrap.setPipelineFactory(() -> {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
pipeline.addLast("helloHandler", new HelloHandler());
return pipeline;
});
bootstrap.bind(new InetSocketAddress(51503));
System.out.println("サービス開始!");
}
}
2. サーバーハンドラ
package com.example.netty.lesson2;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
public class HelloHandler extends SimpleChannelHandler {
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
System.out.println("サーバーからの情報:" + e.getMessage());
String msg = (String) e.getMessage();
System.out.println("サーバーからの情報:" + msg);
super.messageReceived(ctx, e);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
System.out.println("例外発生");
super.exceptionCaught(ctx, e);
}
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("新しい接続");
super.channelConnected(ctx, e);
}
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("接続切断");
super.channelDisconnected(ctx, e);
}
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("接続閉じる");
super.channelClosed(ctx, e);
}
}
3. クライアントコード
package com.example.netty.lesson2;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.ClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
import java.net.InetSocketAddress;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NettyClient {
public static void main(String[] args) {
ClientBootstrap bootstrap = new ClientBootstrap();
ExecutorService boss = Executors.newCachedThreadPool();
ExecutorService work = Executors.newCachedThreadPool();
bootstrap.setFactory(new NioClientSocketChannelFactory(boss, work));
bootstrap.setPipelineFactory(() -> {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());
pipeline.addLast("hiHandler", new HiHandler());
return pipeline;
});
ChannelFuture connect = bootstrap.connect(new InetSocketAddress("127.0.0.1", 51503));
Channel channel = connect.getChannel();
System.out.println("クライアント開始");
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("入力してください:");
channel.write(scanner.next());
}
}
}
4. クライアントハンドラ
package com.example.netty.lesson2;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
public class HiHandler extends SimpleChannelHandler {
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
System.out.println("サーバーからの情報:" + e.getMessage());
String msg = (String) e.getMessage();
System.out.println("サーバーからの情報:" + msg);
ctx.getChannel().write("hi,こんにちは!!");
super.messageReceived(ctx, e);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
System.out.println("例外発生");
super.exceptionCaught(ctx, e);
}
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("新しい接続");
super.channelConnected(ctx, e);
}
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("接続切断");
super.channelDisconnected(ctx, e);
}
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("接続閉じる");
super.channelClosed(ctx, e);
}
}