Netty+Kryo实现高性能网络通信

netty 是 开源的基于java的网络通信框架,其中java对象的传输,netty使用的是java原生的序列化/反序列化实现的,而Kryo是性能更好的java序列化框架,能否让netty和kryo结合,实现高性能的数据通信呢?下面就是如何实现。

 

首先,模仿Netty自带的ObjectEncoder,写一个kryo序列化的ObjectEncoder:

import static org.jboss.netty.buffer.ChannelBuffers.dynamicBuffer;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferOutputStream;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Output;

public class ObjectKryoEncoder extends OneToOneEncoder {
	private static final byte[] LENGTH_PLACEHOLDER = new byte[4];
	
	@Override
	protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
        ChannelBufferOutputStream bout =
            new ChannelBufferOutputStream(dynamicBuffer(
                    4096, ctx.getChannel().getConfig().getBufferFactory()));
        bout.write(LENGTH_PLACEHOLDER);
        
        Kryo kryo = new Kryo();
        Output output = new Output(bout);
        kryo.writeClassAndObject(output, msg);
		output.flush();
		output.close();
		
        ChannelBuffer encoded = bout.buffer();
        encoded.setInt(0, encoded.writerIndex() - 4);
        return encoded;
	}
}

 

接下来,模仿Netty自带的ObjectDecoder,写一个kryo序列化的ObjectDecoder:

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferInputStream;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;

public class ObjectKryoDecoder extends LengthFieldBasedFrameDecoder {
    public ObjectKryoDecoder() {
        this(10485760);
    }

    public ObjectKryoDecoder(int maxObjectSize) {
    	super(maxObjectSize, 0, 4, 0, 4);
    }
    
    @Override
    protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
        ChannelBuffer frame = (ChannelBuffer) super.decode(ctx, channel, buffer);
        if (frame == null) {
            return null;
        }
        Kryo kryo = new Kryo();
		Input input = null;
		try {
			input = new Input(new ChannelBufferInputStream(frame));
			return kryo.readClassAndObject(input);
		} finally {
			input.close();
		}
    }
}

 以上的Encoder和Decoder都是kryo序列化的版本,将其注入ChannelPipelineFactory 中即可:

	ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
	bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
		public ChannelPipeline getPipeline() {
			ChannelPipeline pipeline = Channels.pipeline();
			pipeline.addLast("decoder", new ObjectKryoDecoder());
			pipeline.addLast("encoder", new ObjectKryoEncoder());
			pipeline.addLast("handler", new TimeClientHandler3());
			return pipeline;
		}
	});
......

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值