Netty4.x中文教程系列(四) 对象传输
Netty4.x中文教程系列(四) 对象传输
我们在使用netty的过程中肯定会遇到传输对象的情况,Netty4通过ObjectEncoder和ObjectDecoder来支持。
首先我们定义一个User对象,一定要实现Serializable接口:
package mjorcen.netty.object; import java.io.Serializable; /**
* User: hupeng Date: 14-6-3 Time: 上午1:31
*/
public class User implements Serializable { private int id; private String name; private String cardNo; private String description; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getCardNo() {
return cardNo;
} public void setCardNo(String cardNo) {
this.cardNo = cardNo;
} public String getDescription() {
return description;
} public void setDescription(String description) {
this.description = description;
} @Override
public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + ", cardNo='"
+ cardNo + '\'' + ", description='" + description + '\'' + '}';
}
}
服务端和客户端里,我们自定义的Handler实现如下:
server
package mjorcen.netty.object;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder; public class ObjectTranferServer { private final int port; public ObjectTranferServer(int port) {
this.port = port;
} public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(
new ObjectEncoder(),
new ObjectDecoder(Integer.MAX_VALUE,ClassResolvers.cacheDisabled(null)),
new ObjectTransferServerHandler());
}
}); // Bind and start to accept incoming connections.
b.bind(port).sync().channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
} public static void main(String[] args) throws Exception {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 11000;
}
new ObjectTranferServer(port).run();
}
}
serverHandler
package mjorcen.netty.object; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import java.util.logging.Level;
import java.util.logging.Logger; public class ObjectTransferServerHandler extends ChannelInboundHandlerAdapter { private static final Logger logger = Logger
.getLogger(ObjectTransferServerHandler.class.getName()); @Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
System.out.println(msg);
ctx.writeAndFlush(msg); } // @Override
// public void channelReadComplete(ChannelHandlerContext ctx) throws
// Exception {
// ctx.flush();
// ctx.close();
// } @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
logger.log(Level.WARNING, "Unexpected exception from downstream.",
cause);
ctx.close();
} }
client
package mjorcen.netty.object;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder; public class ObjectTransferClient {
private String host; private int port; private int messageSize; public ObjectTransferClient(String host, int port, int messageSize) {
this.host = host;
this.port = port;
this.messageSize = messageSize;
} public void run() throws InterruptedException {
Bootstrap bootstrap = new Bootstrap();
EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try {
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(
new ObjectEncoder(),
new ObjectDecoder(Integer.MAX_VALUE ,ClassResolvers.cacheDisabled(null)),
new ObjectTransferClientHandler(messageSize));
}
}); ChannelFuture future = bootstrap.connect(host, port).sync(); future.channel().closeFuture().sync();
} finally {
eventLoopGroup.shutdownGracefully();
}
} public static void main(String[] args) throws Exception {
final String host = "localhost";
final int port = 11000;
final int messageSize = 20; new ObjectTransferClient(host, port, messageSize).run();
}
}
clientHandler
package mjorcen.netty.object; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger; public class ObjectTransferClientHandler extends ChannelInboundHandlerAdapter { private static final Logger logger = Logger
.getLogger(ObjectTransferClientHandler.class.getName()); private final List<User> message; /**
* Creates a client-side handler.
*/
public ObjectTransferClientHandler(int messageSize) {
if (messageSize <= 0) {
throw new IllegalArgumentException("firstMessageSize: "
+ messageSize);
}
message = new ArrayList<User>(messageSize);
for (int i = 0; i < messageSize; i++) {
User user = new User();
user.setId(i);
user.setCardNo("420000" + i);
user.setName("hu" + i);
user.setDescription("你觉得这样好吗??真的好吗" + i);
message.add(user); }
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// Send the message to Server
super.channelActive(ctx);
ctx.writeAndFlush(message);
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
// you can use the Object from Server here
System.out.println(msg);
ctx.close();
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
logger.log(Level.WARNING, "Unexpected exception from downstream.",
cause);
ctx.close();
}
}
简单梳理一下思路:
- 通过Netty传递,都需要基于流,以ChannelBuffer的形式传递。所以,Object -> ChannelBuffer.
- Netty提供了转换工具,需要我们配置到Handler。
- 样例从客户端 -> 服务端,单向发消息,所以在客户端配置了编码,服务端解码。如果双向收发,则需要全部配置Encoder和Decoder。
这里需要注意,注册到Server的Handler是有顺序的,如果你颠倒一下注册顺序:
结果就是,会先进入我们自己的业务,再进行解码。这自然是不行的,会强转失败。至此,你应该会用Netty传递对象了吧。
Netty4.x中文教程系列(四) 对象传输的更多相关文章
- Netty4.x中文教程系列(四) ChannelHandler
这篇文章用以解释ChannelHandler.笔者本身在以前写过文章ChannelHandler改动及影响 和 ChannelInitializer 学习 对Netty的.ChannelHandler ...
- Netty4.x中文教程系列(一) 目录及概述
Netty4.x中文教程系列(一)目录及概述 Netty 提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. Netty是一个NIO客户端 服务端框架 ...
- Netty4.x中文教程系列(三) ChannelHandler
Netty4.x中文教程系列(四) ChannelHandler 上一篇文章详细解释了Hello World示例的代码.里面涉及了一些Netty框架的基础. 这篇文章用以解释ChannelHandl ...
- Netty4.x中文教程系列(五)编解码器Codec
Netty4.x中文教程系列(五)编解码器Codec 上一篇文章详细解释了ChannelHandler的相关构架设计,版本和设计逻辑变更等等. 这篇文章主要在于讲述Handler里面的Codec,也就 ...
- Netty4.x中文教程系列(六) 从头开始Bootstrap
Netty4.x中文教程系列(六) 从头开始Bootstrap 其实自从中文教程系列(五)一直不知道自己到底想些什么.加上忙着工作上出现了一些问题.本来想就这么放弃维护了.没想到有朋友和我说百度搜索推 ...
- Netty4.x中文教程系列(二) Hello World !
在中国程序界.我们都是学着Hello World !慢慢成长起来的.逐渐从一无所知到熟悉精通的. 第二章就从Hello World 开始讲述Netty的中文教程. 首先创建一个Java项目.引入一个N ...
- Netty4.x中文教程系列(二) Hello World !<转>
在中国程序界.我们都是学着Hello World !慢慢成长起来的.逐渐从一无所知到熟悉精通的. 第二章就从Hello World 开始讲述Netty的中文教程. 首先创建一个Java项目.引入一个N ...
- struts2官方 中文教程 系列四:Action
先贴个本帖的地址,免得其它网站被爬去了struts2教程 官方系列四:Action 即 http://www.cnblogs.com/linghaoxinpian/p/6905521.html 下载 ...
- Netty4.x中文教程系列(三) Hello World !详解
Netty 中文教程 (二) Hello World !详解 上一篇文章,笔者提供了一个Hello World 的Netty示例. 时间过去了这么久,准备解释一下示例代码. 1.HelloServer ...
随机推荐
- 安卓、java开发软件官网和相关不错的网站软件下载地址
java:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html eclipse:htt ...
- Android 动画学习笔记
Android动画的两种:Frame帧动画.Tween动画(位移动画)[实现:存放目录res/anim] Tween动画:(位移.缩放.旋转):通过对场景里的对象不断做图像变换. 四种效果Alpha. ...
- [转] 利用任务计划重启sqlserver服务
1.建立一个批处理文件restartsqlserver.bat 内容如下: net stop mssqlserver /y net start mssqlser ...
- Python类和实例
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可 ...
- Jquery操作radio,checkbox,select表单操作实现代码
一 .Select jQuery获取Select选择的Text和Value: 1. $("#select_id").change(function(){//code...}); / ...
- C语言中char* 和 char []区别
想要把丢掉的东西捡起来,还是很辛苦啊,今天我就发现,我连char* 和 char []的区别都不知道. 很多人觉得这两个定义效果一样,其实差别很大.以下是个人的一些看法,有不正确的地方望指正. 本质上 ...
- 读书笔记-UIView与控件
1.UIView 在Objective-C中,NSObject是所有类的“根”类.同样,在UIKit框架中,也存在一个如此神奇的类UIView.从继承关系上看,UIView是所有视图的根. 1.1.U ...
- [Bootstrap]组件(一)
Glyphicons字体图标 基类.glyphicon {position/top/display/font-family/} 具体类 {content} --表现在伪元素上 使用要点:a.基类 ...
- zz 如何在Linux下创建与解压zip, tar, tar.gz和tar.bz2文件
January 2nd, 2009 at 10:31 pm Linux 解压, Linux, tar, tar.bz2, tar.gz, tgz, zip, 压缩, 打包, 文档 这么多年来,数据压缩 ...
- C语言实现基于投票规则的细胞自动机
算法介绍 首先我们先看一下“基于投票规则的细胞自动机”的定义: 基于投票规则的细胞自动机,实际上是具有如下限定条件的一种细胞自动机: 状态:0或1: 邻居:中心的3*3邻居: 规则:计数p表示中心的3 ...