1、netty3是nio的封装版本。在使用上面比nio的直接使用更好。nio简单使用都是单线程的方式(比如:一个服务员服务很多客户),但是netty3的方式不一样的是,引入线程池的方式来实现服务的通信(比如:不同的服务员服务不同的客户群体一样)。netty3将入口和实现分成两个线程池。入口:boss,实现:work。实现过程就是当一个客户端进入过后,boss线程池分配一个线程来接待客户,而通过boss来分配具体的服务人work来服务这位客户。
2、netty3的使用是在nio的基础上加入线程池的概念进行实现的,后面我会单独讲一个netty3的源码实现过程。
3、这里写了一点netty3的实现过程。
1)服务端:server和serverHandler
import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; 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 Server { public static void main(String[] args) { //声明服务类 ServerBootstrap serverBootstrap = new ServerBootstrap(); //设定线程池 ExecutorService boss = Executors.newCachedThreadPool(); ExecutorService work = Executors.newCachedThreadPool(); //设置工厂 serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss,work)); //设置管道流 serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); //添加处理方式 channelPipeline.addLast("decode",new StringDecoder()); channelPipeline.addLast("encode",new StringEncoder()); channelPipeline.addLast("server",new ServerHandler()); return channelPipeline; } }); //设置端口 serverBootstrap.bind(new InetSocketAddress(9000)); } }
备注:具体的数据处理交给ServerHandler
import org.jboss.netty.channel.*; public class ServerHandler extends SimpleChannelHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { System.out.println("client:"+e.getMessage()); ctx.getChannel().write(e.getMessage()); super.messageReceived(ctx, e); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { super.exceptionCaught(ctx, e); } @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelConnected(ctx, e); } @Override public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelDisconnected(ctx, e); } @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelClosed(ctx, e); } }
2)客户端:client和clientHandler
import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.*; 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 Client { public static void main(String[] args) { //声明客户端 ClientBootstrap clientBootstrap = new ClientBootstrap(); //设置线程池 ExecutorService boss = Executors.newCachedThreadPool(); ExecutorService work = Executors.newCachedThreadPool(); //设置线程池工厂 clientBootstrap.setFactory(new NioClientSocketChannelFactory(boss,work)); //设置管道工厂 clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); channelPipeline.addLast("decode",new StringDecoder()); channelPipeline.addLast("encode",new StringEncoder()); channelPipeline.addLast("client",new ClientHandler()); return channelPipeline; } }); //连接服务器 ChannelFuture channelFuture = clientBootstrap.connect(new InetSocketAddress("localhost", 9000)); //获取通道 Channel channel = channelFuture.getChannel(); //写入数据 Scanner scanner = new Scanner(System.in); while (true) { channel.write(scanner.next()); } } }
备注:处理的方式基本上和服务端一样
import org.jboss.netty.channel.*; public class ClientHandler extends SimpleChannelHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { System.out.println("server:"+e.getMessage()); super.messageReceived(ctx, e); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { super.exceptionCaught(ctx, e); } @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelConnected(ctx, e); } @Override public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelDisconnected(ctx, e); } @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelClosed(ctx, e); } }
4、这里讲的是netty3的应用过程,应用线程池来实现具体的工作。这样在效率和时间上面都会得到很大的改善