netty 对象序列化传输示例
package object.server.impl; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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 SubReqServer {
public void start(int port) {
NioEventLoopGroup workGroup = new NioEventLoopGroup();
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workGroup);
bootstrap.channel(NioServerSocketChannel.class);
// 配置 NioServerSocketChannel 的 tcp 参数, BACKLOG 的大小
bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
/*
* 使用 weakCachingConcurrentResolver 创建线程安全的 WeakReferenceMap
* ,对类加载器进行缓存
* ,它支持多线程并发访问,当虚拟机内存不足时,会释放缓存中的内存,防止内存泄露,为了房子异常码流和解码错位导致的内存溢出
* ,这里将当个对象序列化之后的字节数组长度设置为1M
*/
ObjectDecoder objectDecoder = new ObjectDecoder(1024 * 1024,
ClassResolvers.weakCachingConcurrentResolver(this
.getClass().getClassLoader())); ch.pipeline().addLast(objectDecoder);
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline().addLast(new SubReqHandler());
}
});
// 绑定端口,随后调用它的同步阻塞方法 sync 等等绑定操作成功,完成之后 Netty 会返回一个 ChannelFuture
// 它的功能类似于的 Future,主要用于异步操作的通知回调.
ChannelFuture channelFuture;
try {
channelFuture = bootstrap.bind(port).sync();
// 等待服务端监听端口关闭,调用 sync 方法进行阻塞,等待服务端链路关闭之后 main 函数才退出.
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
} public static void main(String[] args) {
SubReqServer server = new SubReqServer();
server.start(9091);
}
}
package object.server.impl; import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; public class SubReqHandler extends ChannelHandlerAdapter { @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
cause.printStackTrace();
ctx.close();
super.exceptionCaught(ctx, cause);
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception { System.out.println(msg);
SubscriptResp sub = new SubscriptResp();
ctx.writeAndFlush(sub);
} @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
Client
package object.client.impl; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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 SubReqClient {
public void connect(String host, int port) {
NioEventLoopGroup workGroup = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap();
bootstrap.group(workGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.TCP_NODELAY, true);
bootstrap.handler(new ChannelInitializer<SocketChannel>() { @Override
protected void initChannel(SocketChannel ch) throws Exception {
/*
* 禁止堆类加载器进行缓存,他在基于 OSGI 的动态模块化编程中经常使用,由于 OSGI 可以进行热部署和热升级,当某个
* bundle
* 升级后,它对应的类加载器也将一起升级,因此在动态模块化的编程过程中,很少对类加载器进行缓存,因为他随时可能会发生变化.
*/
ch.pipeline().addLast(
new ObjectDecoder(1024 >> 2, ClassResolvers
.cacheDisabled(getClass().getClassLoader())));
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline().addLast(new SubReqClientHandler());
}
}); // 发起异步链接操作
ChannelFuture future;
try {
future = bootstrap.connect(host, port).sync();
// 等待客户端链路关闭
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
workGroup.shutdownGracefully();
}
} public static void main(String[] args) {
new SubReqClient().connect("localhost", 9091);
}
}
ClientHandler
package object.client.impl; import object.server.impl.SubScriptReq;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; public class SubReqClientHandler extends ChannelHandlerAdapter { @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
cause.printStackTrace();
ctx.close();
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
SubScriptReq req = new SubScriptReq();
req.setSubReq(999);
ctx.writeAndFlush(req);
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
System.out.println(msg);
} @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} }
POJO
package object.server.impl; import java.io.Serializable; public class SubscriptResp implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4923081103118853877L;
private Integer subScriptID;
private String respCode;
private String desc; public Integer getSubScriptID() {
return subScriptID;
} public void setSubScriptID(Integer subScriptID) {
this.subScriptID = subScriptID;
} public String getRespCode() {
return respCode;
} public void setRespCode(String respCode) {
this.respCode = respCode;
} public String getDesc() {
return desc;
} public void setDesc(String desc) {
this.desc = desc;
} @Override
public String toString() {
return "SubscriptResp [subScriptID=" + subScriptID + ", respCode="
+ respCode + ", desc=" + desc + "]";
} }
req
package object.server.impl; import java.io.Serializable; public class SubScriptReq implements Serializable {
/**
*
*/
private static final long serialVersionUID = 4686274228090335845L;
private Integer subReq;
private String userName;
private String productName;
private String address; public Integer getSubReq() {
return subReq;
} public void setSubReq(Integer subReq) {
this.subReq = subReq;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getProductName() {
return productName;
} public void setProductName(String productName) {
this.productName = productName;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
} @Override
public String toString() {
return "SubScriptReq [subReq=" + subReq + ", userName=" + userName
+ ", productName=" + productName + ", address=" + address + "]";
} }
netty 对象序列化传输示例的更多相关文章
- Netty5+Jboss(Marshalling)完成对象序列化传输
TCP在网络通讯的时候,通常在解决TCP粘包.拆包问题的时候,一般会用以下几种方式: 1. 消息定长 例如每个报文的大小固定为200个字节,如果不够,空位补空格: 2. 在消息尾部添加特殊字符进行分割 ...
- netty: marshalling传递对象,传输附件GzipUtils
netty: marshalling传递对象,传输附件GzipUtils 前端与服务端传输文件时,需要双方需要进行解压缩,也就是Java序列化.可以使用java进行对象序列化,netty去传输,但ja ...
- java 对象序列化 RMI
对于一个存在于Java虚拟机中的对象来说,其内部的状态只保持在内存中.JVM停止之后,这些状态就丢失了.在很多情况下,对象的内部状态是需要被持久化下来的.提到持久化,最直接的做法是保存到文件系统或是数 ...
- Java对象序列化与RMI
对于一个存在于Java虚拟机中的对象来说,其内部的状态只保持在内存中.JVM停止之后,这些状态就丢失了.在很多情况下,对象的内部状态是需要被持久化下来的.提到持久化,最直接的做法是保存到文件系统或是数 ...
- Java对象序列化剖析
对象序列化的目的 1)希望将Java对象持久化在文件中 2)将Java对象用于网络传输 实现方式 如果希望一个类的对象可以被序列化/反序列化,那该类必须实现java.io.Serializable接口 ...
- C#对象序列化与反序列化zz
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍........................ ...
- C#对象序列化与反序列化
C#对象序列化与反序列化(转载自:http://www.cnblogs.com/LiZhiW/p/3622365.html) 1. 对象序列化的介绍.......................... ...
- C#[Serializable]在C#中的作用-NET 中的对象序列化
为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本:按值将对象从一个应用程序域发送至另一个应用程序域.例如,序列化可用于在 ASP.NET 中保 ...
- [转载]C#对象序列化与反序列化
文章写的实在是太好了,忍不住转来: http://www.cnblogs.com/LiZhiW/p/3622365.html#_Toc8478 1.对象序列化的介绍 (1).NET支持对象序列化的几种 ...
随机推荐
- jenkins部署node项目
docker run -d --name jenkins -p 8081:8080 -v /home/jenkins_home:/home/jenkins_home jenkins
- C++知识点:拷贝构造函数例子
//拷贝构造函数: //函数参数传递时调用一次拷贝构造函数,给对象赋值时调用一次拷贝构造函数,对象作为参数传递后会被及时销毁. #include <fstream> #include &l ...
- C++程序设计方法6:算法横向拆分
例子1:负载监视器,如何在一个程序中实现对这些不同条件的适应呢? int main() { WindowDisplay display; Monitor monitor(&display); ...
- JS_高程5.引用类型(5)Array类型的操作方法
一.操作方法 1.concat()方法 基于当前数组中的所有项创建一个新数组.具体说,是先创建当前数组的一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组.在没有给concat() ...
- flask之基于DBUtils实现数据库连接池、本地线程、上下文
本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...
- 12、mysql补充
本篇导航: 视图 触发器 事务 存储过程 函数 流程控制 一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可 ...
- .NET的前世今生与将来
笔者注 谨以此文纪念我敬重的2016年9月17日去世的 装配脑袋 逝世两周年 让大家久等了,前后花了1年的时间,几经改版,终于完成撰写了一万字长文,回顾和展望.NET这16年来的成功与失败.最终能成文 ...
- 通过TopShelf快速开发服务程序
我之前在文章中介绍过使用NSSM将exe封装为服务,这种方式我个人是比较喜欢的,一来原始文件不受服务的开发约束,二来也可以提供简单的日志系统.线程守护等功能,是我个人比较倾向的行为.但是,有的场景下, ...
- JavaWeb中过滤器Filter的使用示例
https://github.com/YouXianMing/Java-Web-Study/tree/master/Servlet-Filter 过滤器示例基于以下流程 测试效果如下 web.xml配 ...
- golang time打印出的值是62135596800的来源
' 减去62135596800是将"以公元1年1月1日0点为基准"改成"以1970年1月1日0点"为基准 所以,数据库datetime的默认值 : 0000-0 ...