netty初步
来源:互联网 发布:p衣服的软件 编辑:程序博客网 时间:2024/04/29 20:17
netty是java的高性能socket框架,linux下基epoll,这里不对他多牛逼作分析,网上资料很多,这里针对一般socket的业务作个例子
几个基本概念:
channel类似于socket句柄的抽象
pipeline是每个socket里面的eventHandler的处理响应链
每个socket(channel)绑定一个pipeline,,每个pipeline绑定若干个handler,netty里面的handler,专门用来处理和业务有关的东西,handler有upHandler和downHandler,down用来处理发包,up用来处理收包,大概的示例图看这里
注意上面的123的顺序,很重要,在netty里面,处理顺序如图,对于up类的收包处理,最靠近收包层的顺序越靠前;对于down类的包处理,最靠近收包层的顺序越靠后
还有一些encoder和decoder,encoder用来在发包之前进行加密,decoder在收包以后进行解码,然后业务数据跳到事件处理流程。
下面具体上代码,版本是netty3.6
MessageClientHandler.java
1 package com.netty.test.client; 2 3 import java.util.logging.Level; 4 import java.util.logging.Logger; 5 6 import org.jboss.netty.channel.ChannelHandlerContext; 7 import org.jboss.netty.channel.ChannelStateEvent; 8 import org.jboss.netty.channel.ExceptionEvent; 9 import org.jboss.netty.channel.MessageEvent;10 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;11 12 public class MessageClientHandler extends SimpleChannelUpstreamHandler {13 14 private static final Logger logger = Logger.getLogger(15 MessageClientHandler.class.getName());16 17 18 @Override19 public void channelConnected(20 ChannelHandlerContext ctx, ChannelStateEvent e) {21 String message = "hello kafka0102";22 e.getChannel().write(message);23 }24 25 @Override26 public void messageReceived(27 ChannelHandlerContext ctx, MessageEvent e) {28 // Send back the received message to the remote peer.29 System.err.println("client messageReceived send message "+e.getMessage());30 try {31 Thread.sleep(1000*3);32 } catch (Exception ex) {33 ex.printStackTrace();34 }35 e.getChannel().write(e.getMessage());36 }37 38 @Override39 public void exceptionCaught(40 ChannelHandlerContext ctx, ExceptionEvent e) {41 // Close the connection when an exception is raised.42 logger.log(43 Level.WARNING,44 "Unexpected exception from downstream.",45 e.getCause());46 e.getChannel().close();47 }48 }
MessageDecoder.java
1 package com.netty.test.client; 2 import org.jboss.netty.buffer.ChannelBuffer; 3 import org.jboss.netty.channel.Channel; 4 import org.jboss.netty.channel.ChannelHandlerContext; 5 import org.jboss.netty.handler.codec.frame.FrameDecoder; 6 7 public class MessageDecoder extends FrameDecoder { 8 9 @Override10 protected Object decode(11 ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {12 if (buffer.readableBytes() < 4) {13 return null;//(1)14 }15 int dataLength = buffer.getInt(buffer.readerIndex());16 if (buffer.readableBytes() < dataLength + 4) {17 return null;//(2)18 }19 20 buffer.skipBytes(4);//(3)21 byte[] decoded = new byte[dataLength];22 buffer.readBytes(decoded);23 String msg = new String(decoded);//(4)24 return msg;25 }26 }
MessageEncoder.java
1 package com.netty.test.client; 2 import org.jboss.netty.buffer.ChannelBuffer; 3 import org.jboss.netty.buffer.ChannelBuffers; 4 import org.jboss.netty.channel.Channel; 5 import org.jboss.netty.channel.ChannelHandlerContext; 6 import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; 7 8 public class MessageEncoder extends OneToOneEncoder { 9 10 @Override11 protected Object encode(12 ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {13 if (!(msg instanceof String)) {14 return msg;//(1)15 }16 17 String res = (String)msg;18 byte[] data = res.getBytes();19 int dataLength = data.length;20 ChannelBuffer buf = ChannelBuffers.dynamicBuffer();//(2)21 buf.writeInt(dataLength);22 buf.writeBytes(data);23 return buf;//(3)24 }25 }
用来测试的TestClientDownHandlerA.java
1 package com.netty.test.client; 2 3 import org.jboss.netty.channel.ChannelEvent; 4 import org.jboss.netty.channel.ChannelHandlerContext; 5 import org.jboss.netty.channel.SimpleChannelDownstreamHandler; 6 7 public class TestClientDownHandlerA extends SimpleChannelDownstreamHandler { 8 9 public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)10 throws Exception {11 System.err.println("test client Down handlerA ");12 13 super.handleDownstream(ctx, e);14 }15 }
用来测试的TestClientDownHandlerB.java
1 package com.netty.test.client; 2 3 import org.jboss.netty.channel.ChannelEvent; 4 import org.jboss.netty.channel.ChannelHandlerContext; 5 import org.jboss.netty.channel.SimpleChannelDownstreamHandler; 6 7 public class TestClientDownHandlerB extends SimpleChannelDownstreamHandler { 8 9 public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)10 throws Exception {11 System.err.println("test client Down handlerB ");12 13 super.handleDownstream(ctx, e);14 }15 }
MessageClientPipelineFactory.java
1 package com.netty.test.client; 2 3 import org.jboss.netty.channel.ChannelPipeline; 4 import org.jboss.netty.channel.ChannelPipelineFactory; 5 import org.jboss.netty.channel.Channels; 6 7 import com.netty.test.client.MessageDecoder; 8 import com.netty.test.client.MessageEncoder; 9 10 public class MessageClientPipelineFactory implements ChannelPipelineFactory {11 12 public ChannelPipeline getPipeline() throws Exception {13 ChannelPipeline pipeline = Channels.pipeline();14 15 pipeline.addLast("decoder", new MessageDecoder());16 pipeline.addLast("encoder", new MessageEncoder());17 pipeline.addLast("handler", new MessageClientHandler());18 19 pipeline.addFirst("testClientDownHandlerA", new TestClientDownHandlerA());20 pipeline.addFirst("testClientDownHandlerB", new TestClientDownHandlerB());21 22 return pipeline;23 }24 }
MessageClient.java
1 package com.netty.test.client; 2 3 import java.net.InetSocketAddress; 4 import java.util.concurrent.Executors; 5 import org.jboss.netty.bootstrap.ClientBootstrap; 6 import org.jboss.netty.channel.ChannelFuture; 7 import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; 8 9 public class MessageClient {10 11 public static void main(String[] args) throws Exception {12 // Parse options.13 String host = "127.0.0.1";14 int port = 8888;15 // Configure the client.16 ClientBootstrap bootstrap = new ClientBootstrap(17 new NioClientSocketChannelFactory(18 Executors.newCachedThreadPool(),19 Executors.newCachedThreadPool()));20 // Set up the event pipeline factory.21 bootstrap.setPipelineFactory(new MessageClientPipelineFactory());22 // Start the connection attempt.23 ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));24 // Wait until the connection is closed or the connection attempt fails.25 future.getChannel().getCloseFuture().awaitUninterruptibly();26 // Shut down thread pools to exit.27 bootstrap.releaseExternalResources();28 }29 }
客户端代码完成
以下为服务端测试代码
MessageDecoder和Messagencoder照抄,这个都是一样的
MessageServerHandler.java
1 package com.netty.test.server; 2 import java.util.logging.Level; 3 import java.util.logging.Logger; 4 5 import org.jboss.netty.channel.ChannelHandlerContext; 6 import org.jboss.netty.channel.ExceptionEvent; 7 import org.jboss.netty.channel.MessageEvent; 8 import org.jboss.netty.channel.SimpleChannelUpstreamHandler; 9 10 public class MessageServerHandler extends SimpleChannelUpstreamHandler {11 12 private static final Logger logger = Logger.getLogger(13 MessageServerHandler.class.getName());14 15 @Override16 public void messageReceived(17 ChannelHandlerContext ctx, MessageEvent e) {18 if (!(e.getMessage() instanceof String)) {19 return;//(1)20 }21 String msg = (String) e.getMessage();22 System.err.println("got msg:"+msg);23 e.getChannel().write(msg);//(2)24 }25 26 @Override27 public void exceptionCaught(28 ChannelHandlerContext ctx, ExceptionEvent e) {29 logger.log(30 Level.WARNING,31 "Unexpected exception from downstream.",32 e.getCause());33 e.getChannel().close();34 }35 }
TestServerUpHandlerA.java
1 package com.netty.test.server; 2 3 import org.jboss.netty.channel.ChannelHandlerContext; 4 import org.jboss.netty.channel.ExceptionEvent; 5 import org.jboss.netty.channel.MessageEvent; 6 import org.jboss.netty.channel.SimpleChannelUpstreamHandler; 7 8 public class TestServerUpHandlerA extends SimpleChannelUpstreamHandler { 9 10 @Override11 public void messageReceived(12 ChannelHandlerContext ctx, MessageEvent e) {13 // Send back the received message to the remote peer.14 System.err.println("server test upHandlerA get message "+e.getMessage());15 16 try {17 super.messageReceived(ctx, e);18 } catch (Exception e1) {19 // TODO Auto-generated catch block20 e1.printStackTrace();21 }22 }23 24 @Override25 public void exceptionCaught(26 ChannelHandlerContext ctx, ExceptionEvent e) {27 28 e.getChannel().close();29 }30 }
TestServerUpHandlerB.java
1 package com.netty.test.server; 2 3 import org.jboss.netty.channel.ChannelHandlerContext; 4 import org.jboss.netty.channel.ExceptionEvent; 5 import org.jboss.netty.channel.MessageEvent; 6 import org.jboss.netty.channel.SimpleChannelUpstreamHandler; 7 8 public class TestServerUpHandlerB extends SimpleChannelUpstreamHandler { 9 10 @Override11 public void messageReceived(12 ChannelHandlerContext ctx, MessageEvent e) {13 // Send back the received message to the remote peer.14 System.err.println("server test upHandlerB get message "+e.getMessage());15 16 try {17 super.messageReceived(ctx, e);18 } catch (Exception e1) {19 // TODO Auto-generated catch block20 e1.printStackTrace();21 }22 }23 24 @Override25 public void exceptionCaught(26 ChannelHandlerContext ctx, ExceptionEvent e) {27 28 e.getChannel().close();29 }30 }
MessageServerPipelineFactory.java
1 package com.netty.test.server; 2 3 import org.jboss.netty.channel.ChannelPipeline; 4 import org.jboss.netty.channel.ChannelPipelineFactory; 5 import org.jboss.netty.channel.Channels; 6 7 public class MessageServerPipelineFactory implements 8 ChannelPipelineFactory { 9 10 public ChannelPipeline getPipeline() throws Exception {11 ChannelPipeline pipeline = Channels.pipeline();12 13 pipeline.addLast("decoder", new MessageDecoder());14 pipeline.addLast("encoder", new MessageEncoder());15 pipeline.addLast("handler", new MessageServerHandler());16 17 // pipeline.addFirst("testServerUpHandlerA", new TestServerUpHandlerA());18 // pipeline.addFirst("testServerUpHandlerB", new TestServerUpHandlerB());19 20 return pipeline;21 }22 }
MessageServer.java
1 package com.netty.test.server; 2 3 import java.net.InetSocketAddress; 4 import java.util.concurrent.Executors; 5 import org.jboss.netty.bootstrap.ServerBootstrap; 6 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; 7 8 public class MessageServer { 9 10 public static void main(String[] args) throws Exception {11 // Configure the server.12 ServerBootstrap bootstrap = new ServerBootstrap(13 new NioServerSocketChannelFactory(14 Executors.newCachedThreadPool(),15 Executors.newCachedThreadPool()));16 17 // Set up the default event pipeline.18 bootstrap.setPipelineFactory(new MessageServerPipelineFactory());19 20 // Bind and start to accept incoming connections.21 bootstrap.bind(new InetSocketAddress(8888));22 }23 }
通过测试,可以发现handler的处理顺序,和图上面的是一致的;还有可以参考下encoder和decoder的写法,改改,直接用于项目。
- netty初步
- Netty 初步
- Netty使用初步
- netty初步使用
- netty初步使用2
- Netty使用初步
- Netty使用初步
- Netty使用初步
- Netty使用初步
- Netty 初步介绍
- netty初步学习
- Netty使用初步(转)
- Netty初步之hello world
- Netty初步之hello world
- Netty初步之Hello World
- Netty初步之hello world
- Netty开源库的初步使用
- Netty初步之Hello World
- 手把手叫你写自定义ProgressDialog控件
- Xcode 替换功能详解
- xcode6如何导入全局头文件
- 深入理解Java:注解(Annotation)(二)——自定义注解入门
- 在switch-case中定义变量时当心被“穿越”
- netty初步
- JMX RMI相关
- 使用Quick-Cocos2d-x搭建一个横版过关游戏(一) CCStore
- 为什么要搭建自动化测试框架
- Struts1实现一次下载两个文件
- 2014 Facebook Hacker Cup 资格赛 第二题 二进制模拟
- postgresql模块——pg_stat_statements详解和安装测试
- 2015-1-14 sc源码分析
- 数组排序