Netty入门二 之解编码
来源:互联网 发布:网络教育的英语作文 编辑:程序博客网 时间:2024/06/10 05:44
关键字:Netty解编码,JBoss Marshalling,
代码在 https://github.com/zhaikaishun/NettyTutorial 在SocketIO_02 kaishun.netty.serial下
Netty解编码技术
解编码技术,说白了就是java序列化技术,序列化的目的就两个,第一进行网络传输,第二对象持久化
虽然我们可以使用java进行对象序列化,netty去传输,但是java序列化的硬伤太多,比如java序列化没法跨语言、序列化够码流太大、序列化性能太低等等…
主流的编码解码框架:
JBoss 的 Marshalling包
google的Protobuf
给予Protobuf的Kyro
MessagePack框架
JBoss Marshalling
Jboss Marshalling是一个java对象序列化包,对jdk默认的序列化框架进行了优化,但又保持跟java.io.Serializable接口的兼容,同时增加了一些可调的参数和附加特性,
类库 jboss-marshalling-1.3.0、jboss-marshalling-serial-1.3.0
Jboss Marshalling与Netty结合后进行序列化对象的代码编写非常简单,我们一起来看一下
首先有个MarshallingCodeCFactory类
这个类不需要看懂,就要有一个这个类就好了
/** * Marshalling工厂 * @author(alienware) * @since 2014-12-16 */public final class MarshallingCodeCFactory { /** * 创建Jboss Marshalling解码器MarshallingDecoder * @return MarshallingDecoder */ public static MarshallingDecoder buildMarshallingDecoder() { //首先通过Marshalling工具类的精通方法获取Marshalling实例对象 参数serial标识创建的是java序列化工厂对象。 final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial"); //创建了MarshallingConfiguration对象,配置了版本号为5 final MarshallingConfiguration configuration = new MarshallingConfiguration(); configuration.setVersion(5); //根据marshallerFactory和configuration创建provider UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration); //构建Netty的MarshallingDecoder对象,俩个参数分别为provider和单个消息序列化后的最大长度 MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024 * 1024 * 1); return decoder; } /** * 创建Jboss Marshalling编码器MarshallingEncoder * @return MarshallingEncoder */ public static MarshallingEncoder buildMarshallingEncoder() { final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial"); final MarshallingConfiguration configuration = new MarshallingConfiguration(); configuration.setVersion(5); MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration); //构建Netty的MarshallingEncoder对象,MarshallingEncoder用于实现序列化接口的POJO对象序列化为二进制数组 MarshallingEncoder encoder = new MarshallingEncoder(provider); return encoder; }}
Server端其他基本不变,就这里
.childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel sc) throws Exception { sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder()); sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder()); sc.pipeline().addLast(new ServerHandler()); } });
Client端也是这里有变化
.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder()); sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder()); sc.pipeline().addLast(new ClientHandler()); } }); for(int i = 0; i < 5; i++ ){ Req req = new Req(); req.setId("" + i); req.setName("pro" + i); req.setRequestMessage("数据信息" + i); // String path = System.getProperty("user.dir") + File.separatorChar + "sources" + File.separatorChar + "001.jpg";// File file = new File(path);// FileInputStream in = new FileInputStream(file);// byte[] data = new byte[in.available()];// in.read(data);// in.close();// req.setAttachment(GzipUtils.gzip(data)); cf.channel().writeAndFlush(req); }
Req类
public class Req implements Serializable{ private static final long SerialVersionUID = 1L; private String id ; private String name ; private String requestMessage ; private byte[] attachment; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRequestMessage() { return requestMessage; } public void setRequestMessage(String requestMessage) { this.requestMessage = requestMessage; } public byte[] getAttachment() { return attachment; } public void setAttachment(byte[] attachment) { this.attachment = attachment; }}
Resp类
public class Resp implements Serializable{ private static final long serialVersionUID = 1L; private String id; private String name; private String responseMessage; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getResponseMessage() { return responseMessage; } public void setResponseMessage(String responseMessage) { this.responseMessage = responseMessage; }}
ClientHandler
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try { Resp resp = (Resp)msg; System.out.println("Client : " + resp.getId() + ", " + resp.getName() + ", " + resp.getResponseMessage()); } finally { ReferenceCountUtil.release(msg); } }
ServerHandler
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Req req = (Req)msg; System.out.println("Server : " + req.getId() + ", " + req.getName() + ", " + req.getRequestMessage());// byte[] attachment = GzipUtils.ungzip(req.getAttachment());//// String path = System.getProperty("user.dir") + File.separatorChar + "receive" + File.separatorChar + "001.jpg";// FileOutputStream fos = new FileOutputStream(path);// fos.write(attachment);// fos.close(); Resp resp = new Resp(); resp.setId(req.getId()); resp.setName("resp" + req.getId()); resp.setResponseMessage("响应内容" + req.getId()); ctx.writeAndFlush(resp);//.addListener(ChannelFutureListener.CLOSE); }
总结上面的代码:
其实只需要在Server和Client端加上这两个,其他方法还是一样的。
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder()); sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
补充: 如果还想进行大文件(例如图片视频等传输),将上面的注释的代码打开即可,这块代码还使用了Gzip进行压缩,压缩之后再进行传输,这是需要注意的。
特别感谢互联网架构师白鹤翔老师,本文大多出自他的视频讲解。
笔者主要是记录笔记,以便之后翻阅,正所谓好记性不如烂笔头,烂笔头不如云笔记
- Netty入门二 之解编码
- Netty (二) 入门
- Netty学习之二
- Netty权威指南之Netty入门应用
- Netty入门之-http文件服务器
- Netty入门之 TimeServer && TimeClient
- Netty学习纪要之编码与解码
- Netty入门应用之第一个netty项目
- Netty 学习笔记之二 Netty 核心概念
- 【Netty入门】Netty概述
- Netty权威指南之NIO入门
- netty探索之入门前言篇
- Netty入门三之最佳实践
- 深入浅出Netty之二 server启动
- netty学习之二:ByteBuf解读
- netty源码分析 之二 transport(bootstrap)
- Netty 源码分析之 EventLoop(二) (最重要)
- Netty 入门
- CITE2017倒计时,开启智能时代
- 王思聪“包养”电竞后 万达觉得可以开攻游戏行业了
- Ubuntu Unity 已死,但 Ubuntu 在云端依然受欢迎
- 最美曲面屏手机 vivo Xplay6 面纱下全是黑科技
- Lyft获5亿美元融资,能否狙击丑闻缠身的Uber?
- Netty入门二 之解编码
- Oracle之查询对应索引的情况
- 安卓UI控件-ViewAnimator及其子类
- 类的私有变量
- TensorFlow自定义损失函数
- 苹果推出视频制作应用Clips,人工智能特性是亮点
- 任正非讲话回应华为“清理34岁员工”传闻,并称要有称霸世界的雄心
- 周鸿祎:通用型的人工智能都是骗子,必须结合垂直领域
- 环保部与腾讯达成战略合作 探索互联网+环保新模式