来斌 2013-04-23
网络传输的时候采用的是流的形式,所以一个对象要发出去,并且在服务端要收到一个完整的对象,就要相应的编码解码的过程,这个例子向您展示netty的ObjectEncoder和ObjectDecoder编码解码的过程,代码写的比较简单而且注释比较多就直接用代码了
Server 服务器端的启动程序
package com.my.day2; import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; /** * @Title: Server.java * @Package com.my.day2 * @Description: TODO * @author jimmy [email protected] * @date 2013-4-22 下午8:06:41 */ public class Server { public void run(){ NioServerSocketChannelFactory channelFactory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap bootstrap = new ServerBootstrap(channelFactory); bootstrap.setPipelineFactory(new ServerChannelPipelineFactory()); bootstrap.setOption("tcpNoDelay", true); bootstrap.setOption("keepAlive", true); bootstrap.bind(new InetSocketAddress(8080)); } }
ServerChannelPipelineFactory
package com.my.day2; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.Channels; import org.jboss.netty.handler.codec.serialization.ClassResolvers; import org.jboss.netty.handler.codec.serialization.ObjectDecoder; /** * @Title: MyChannelFactory.java * @Package com.my.day2 * @Description: 自定义ChannelPipelineFactory * @author jimmy [email protected] * @date 2013-4-22 下午8:08:35 */ public class ServerChannelPipelineFactory implements ChannelPipelineFactory{ @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); /** * 往流水线里添加任务,这里写netty聊天的时候主要的协议解析和逻辑处理 * 例如1.我要对我传送的内容进行加密解密 * 2.我要确定每次客户端传送给服务端的内容是多少 * 3.我要对根究客户端发送的内容确定调用哪端业务逻辑 * 4.netty框架本身自带了很多Encode和DeCode */ channelPipeline.addLast("objectDecode", new ObjectDecoder(ClassResolvers.cacheDisabled(this.getClass().getClassLoader()))); channelPipeline.addLast("myhandler", new ServerHandler()); return channelPipeline; } }
ServerHandler
package com.my.day2; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; /** * @Title: ServerHandler.java * @Package com.my.day2 * @Description: TODO * @author jimmy [email protected] * @date 2013-4-22 下午8:50:46 */ public class ServerHandler extends SimpleChannelUpstreamHandler{ @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { User user = (User) e.getMessage(); System.out.println("form client...." + user.getName()); super.messageReceived(ctx, e); } @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { System.out.println("服务器端进来一个连接"); super.channelConnected(ctx, e); } }
Client
package com.my.day2; import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; /** * @Title: Client.java * @Package com.my.day2 * @Description: TODO * @author jimmy [email protected] * @date 2013-4-22 下午8:57:02 */ public class Client { public void run(){ ClientBootstrap bootstap = new ClientBootstrap(); NioClientSocketChannelFactory channelFactory = new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); bootstap.setFactory(channelFactory); bootstap.setPipelineFactory(new ClientChannelPipelineFactory()); bootstap.setOption("tcpNoDelay", true); bootstap.setOption("keepAlive", true); ChannelFuture future = bootstap.connect(new InetSocketAddress(8080)); User user = new User(); user.setName("xuehan"); user.setPassword("maybe"); future.getChannel().write(user); } }
ClientChannelPipelineFactory
package com.my.day2; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.Channels; import org.jboss.netty.handler.codec.serialization.ObjectEncoder; /** * @Title: MyChannelFactory.java * @Package com.my.day2 * @Description: 自定义ChannelPipelineFactory * @author jimmy [email protected] * @date 2013-4-22 下午8:08:35 */ public class ClientChannelPipelineFactory implements ChannelPipelineFactory{ @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); /** * 往流水线里添加任务,这里写netty聊天的时候主要的协议解析和逻辑处理 * 例如1.我要对我传送的内容进行加密解密 * 2.我要确定每次客户端传送给服务端的内容是多少 * 3.我要对根究客户端发送的内容确定调用哪端业务逻辑 * 4.netty框架本身自带了很多Encode和DeCode */ channelPipeline.addLast("objectEncode", new ObjectEncoder()); channelPipeline.addLast("myhandler", new ClientHandler()); return channelPipeline; } }
测试类TestServer
package com.my.day2; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelDownstreamHandler; /** * @Title: ClientHandler.java * @Package com.my.day2 * @Description: TODO * @author jimmy [email protected] * @date 2013-4-22 下午9:02:50 */ public class ClientHandler extends SimpleChannelDownstreamHandler{ @Override public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception { super.writeRequested(ctx, e); } @Override public void bindRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { // TODO Auto-generated method stub super.bindRequested(ctx, e); } @Override public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { System.out.println("客户端请求连接"); super.connectRequested(ctx, e); } }
测试类TestServer
package com.my.day2; /** * @Title: Test.java * @Package com.my.day2 * @Description: TODO * @author jimmy [email protected] * @date 2013-4-22 下午9:05:02 */ public class TestServer { public static void main(String[] args) throws InterruptedException { Server server = new Server(); server.run(); Thread.sleep(1000); Client client = new Client(); client.run(); } }
User
package com.my.day2; import java.io.Serializable; /** * @Title: User.java * @Package com.my.day2 * @Description: 用于网络传输的对象必须序列化否则无法传送 * @author jimmy [email protected] * @date 2013-4-23 下午8:41:59 */ public class User implements Serializable{ private static final long serialVersionUID = -7198306226394014411L; private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
这是一个完整的例子用的netty的maven配置文件是
<dependency> <groupId>io.netty</groupId> <artifactId>netty</artifactId> <version>3.5.6.Final</version> </dependency>
附件是可以运行代码,依赖jar文件请读者自己去下载