今天尝试使用了Netty框架,感觉使用上也非常方便,具体效率问题,在接下来的博客会详细解读:
NioServerSocketChannelFactory创建服务端的ServerSocketChannel,采用多线程执行非阻塞IO,和Mina的设计
模式一样,都采用了Reactor模式。其中bossExecutor、workerExecutor是两个线程池,bossExecutor用来接收客户端连接,workerExecutor用来执行非阻塞的IO操作,主要是read,write。
package netty; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelFactory; 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.Executors; /** * Created by IntelliJ IDEA. * User: flychao88 * Date: 12-6-6 * Time: 上午10:14 * To change this template use File | Settings | File Templates. */ public class DiscardServer { public static void main(String[] args) throws Exception { ChannelFactory factory = new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap bootstrap = new ServerBootstrap (factory); bootstrap.setPipelineFactory(new ChannelPipelineFactory() { public ChannelPipeline getPipeline() { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("encode",new StringEncoder()); pipeline.addLast("decode",new StringDecoder()); pipeline.addLast("handler",new DiscardServerHandler()); return pipeline; } }); bootstrap.setOption("child.tcpNoDelay", true); bootstrap.setOption("child.keepAlive", true); bootstrap.bind(new InetSocketAddress(8080)); } }
package netty; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.*; /** * Created by IntelliJ IDEA. * User: flychao88 * Date: 12-6-6 * Time: 上午10:10 * To change this template use File | Settings | File Templates. */ public class DiscardServerHandler extends SimpleChannelUpstreamHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { System.out.println("服务器接收1:"+e.getMessage()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { e.getCause().printStackTrace(); Channel ch = e.getChannel(); ch.close(); } }
package netty; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.ChannelFactory; 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.NioClientSocketChannelFactory; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; import java.net.InetSocketAddress; import java.util.concurrent.Executors; /** * Created by IntelliJ IDEA. * User: flychao88 * Date: 12-6-6 * Time: 上午10:21 * To change this template use File | Settings | File Templates. */ public class TimeClient { public static void main(String[] args) throws Exception { ChannelFactory factory = new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ClientBootstrap bootstrap = new ClientBootstrap(factory); bootstrap.setPipelineFactory(new ChannelPipelineFactory() { public ChannelPipeline getPipeline() { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("encode",new StringEncoder()); pipeline.addLast("decode",new StringDecoder()); pipeline.addLast("handler",new TimeClientHandler()); return pipeline; } }); bootstrap.setOption("tcpNoDelay" , true); bootstrap.setOption("keepAlive", true); bootstrap.connect (new InetSocketAddress("127.0.0.1", 8080)); } }
package netty; /** * Created by IntelliJ IDEA. * User: flychao88 * Date: 12-6-6 * Time: 上午10:22 * To change this template use File | Settings | File Templates. */ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.*; import java.util.Date; public class TimeClientHandler extends SimpleChannelUpstreamHandler { @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { e.getChannel().write("abcd"); } @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { e.getChannel().close(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { e.getCause().printStackTrace(); e.getChannel().close(); } }