netty5.0的序列化与反序列化ObjectDecoder和ObjectEncoder

import java.io.Serializable;

public class SubscribeReq implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private int subReqID;
	
	private String userName;
	
	private String productName;
	
	private String phoneNumber;
	
	private String address;

	public int getSubReqID() {
		return subReqID;
	}

	public void setSubReqID(int subReqID) {
		this.subReqID = subReqID;
	}

	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 getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Override
	public String toString() {
		return "SubscribeReq [subReqID=" + subReqID + ", userName=" + userName
				+ ", productName=" + productName + ", phoneNumber="
				+ phoneNumber + ", address=" + address + "]";
	}
}
import java.io.Serializable;

public class SubscribeResp implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private int subReqID;
	
	private int respCode;
	
	private String desc;

	public int getSubReqID() {
		return subReqID;
	}

	public void setSubReqID(int subReqID) {
		this.subReqID = subReqID;
	}
	
	public int getRespCode() {
		return respCode;
	}

	public void setRespCode(int respCode) {
		this.respCode = respCode;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	@Override
	public String toString() {
		return "SubscribeResp [subReqID=" + subReqID + ", respCode=" + respCode
				+ ", desc=" + desc + "]";
	}
}
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class SubReqServer {

	public void bind(int port) {
	  // 服务器线程组 用于网络事件的处理 一个用于服务器接收客户端的连接
      // 另一个线程组用于处理SocketChannel的网络读写
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		
		try {
			 //NIO服务器端的辅助启动类 降低服务器开发难度
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup)
			 .channel(NioServerSocketChannel.class)    // 类似NIO中serverSocketChannel
			 .option(ChannelOption.SO_BACKLOG, 100)   // 配置TCP参数
			 .handler(new LoggingHandler(LogLevel.INFO))
			 .childHandler(new ChannelInitializer<SocketChannel>() {
				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					ch.pipeline().addLast(new ObjectDecoder(1024*1024, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader()))); //objectdecoder
					ch.pipeline().addLast(new ObjectEncoder());  //objectdecoder
					ch.pipeline().addLast(new SubReqServerHandler());
				}
			 }
			); // 最后绑定I/O事件的处理类
			// 服务器启动后 绑定监听端口 同步等待成功 主要用于异步操作的通知回调 回调处理用的ChildChannelHandler
			ChannelFuture f = b.bind(port).sync();
			System.out.println("The time Server is start : "+port);
          // 等待服务端监听端口关闭
			f.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally{
			// 优雅退出 释放线程池资源
			workerGroup.shutdownGracefully();
          bossGroup.shutdownGracefully();
          System.out.println("服务器优雅的释放了线程资源...");
		}
	}
	
	public static void main(String[] args) {
		int port = 8080;
		
		if(null != args && args.length > 0) {
			try {
				port = Integer.parseInt(args[0]);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		
		new SubReqServer().bind(port);
	}

}
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class SubReqServerHandler extends ChannelHandlerAdapter {

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		SubscribeReq req = (SubscribeReq)msg;
		if("kobe".equalsIgnoreCase(req.getUserName())) {
			System.out.println("Service accept client subscribe req : ["+req.toString()+"]");
			ctx.writeAndFlush(resp(req.getSubReqID()));
		}
	}
	
	private Object resp(int subReqID) {
		SubscribeResp resp = new SubscribeResp();
		resp.setSubReqID(subReqID);
		resp.setRespCode(0);
		resp.setDesc("kobe is receive order, 3 days later, send to the address");
		return resp;
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		cause.printStackTrace();
		ctx.close();
	}
}
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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;

/**
 * client 
 * @author 
 *
 */
public class SubReqClient {

	/**
	 * 连接服务器
	 * @param host
	 * @param port
	 */
	public void connect(String host, int port) {
		//配置客户端nio线程组
		EventLoopGroup group = new NioEventLoopGroup();
		
		try {
			//客户端辅助启动类 对客户端配置
			Bootstrap b = new Bootstrap();
			b.group(group).channel(NioSocketChannel.class)
			 .option(ChannelOption.TCP_NODELAY, true)
			 .handler(new ChannelInitializer<SocketChannel>() {
				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					ch.pipeline().addLast(new ObjectDecoder(1024*1024, ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));
					ch.pipeline().addLast(new ObjectEncoder());
					ch.pipeline().addLast(new SubReqClientHandler());
				}
			 });
			//异步链接服务器 同步等待链接成功
			 ChannelFuture f = b.connect(host, port).sync();
			//等待链接关闭
			 f.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally{
			group.shutdownGracefully();
			System.out.println("客户端优雅的释放了线程资源...");
		}
	}

	public static void main(String[] args) {
		int port = 8080;
		if(null != args && args.length > 0) {
			try {
				port = Integer.parseInt(args[0]);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		
		new SubReqClient().connect("127.0.0.1", port);
	}
}
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class SubReqClientHandler extends ChannelHandlerAdapter {
	public SubReqClientHandler() {
		
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		for(int i=0; i<10; i++) {
			ctx.write(subReq(i));
		}
		ctx.flush();
	}

	private SubscribeReq subReq(int i) {
		SubscribeReq subscribeReq = new SubscribeReq();
		subscribeReq.setSubReqID(i);
		subscribeReq.setUserName("kobe");
		subscribeReq.setProductName("effect in java");
		subscribeReq.setPhoneNumber("13875XXXXXX");
		subscribeReq.setAddress("广东深圳南山");
		return subscribeReq;
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		System.out.println("Receive server response : ["+ msg +"]");
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		cause.printStackTrace();
		ctx.close();
	}
	
}

Netty的ObjectEncoder编码器可以自动对订购应答消息进行序列化,然后发送给客户端,客户端的ObjectDecoder解码器对码流进行反序列化,获得订购请求应答消息。

你可能感兴趣的:(netty5.0的序列化与反序列化ObjectDecoder和ObjectEncoder)