2、编解码、序列化、Google Protobuf编解码

版权声明:如果觉得文章对你有用,转载不需要联系作者,但请注明出处 https://blog.csdn.net/jinxin70/article/details/86618135

Java的序列化

Java提供的序列化机制,涉及到两个对象输入输出流类,ObjectInputStream,ObjectOutputStream

Java序列化的目的是网络传输对象持久化

序列化,在网络传输中,将Java对象编码为字节数组或者ByteBuffer对象

反序列化,将从远程服务读取到的ByteBuffer对象或者字节数组解码为Java对象。

Java序列化的缺点:

1、无法跨语言

2、序列化后的码流太大

3、序列化性能差

Protobuf

Protobuf使用二进制编码

平台无关的数据描述文件

优秀的代码生成机制

Protobuf使用和整合Netty开发

下载地址:https://github.com/protocolbuffers/protobuf/releases

IDEA有protobuf代码生成插件,Maven也有,但是我试了不太好用。

我的IDEA是2018.3.1,几款IDEA插件安装了都没有效果。

Maven插件网上也搜了,试了,但是没有成功。想来这些插件只是为了提升生产力的一种途径,就不折腾了。

实验的代码,是使用官网软件的命令行方式生成的代码。

Netty的protobuf服务端:

SubReqServerHandler.java

Netty的protobuf客户端:

SubReqClientHandler.java

public class SubReqClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * Creates a client-side handler.
     */
    public SubReqClientHandler() {
    }

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

    private SubscribeReqProto.SubscribeReq subReq(int i) {
        SubscribeReqProto.SubscribeReq.Builder builder = SubscribeReqProto.SubscribeReq
                .newBuilder();
        builder.setSubReqID(i);
        builder.setUserName("Lilinfeng");
        builder.setProductName("Netty Book For Protobuf");
        List<String> address = new ArrayList<>();
        address.add("NanJing YuHuaTai");
        address.add("BeiJing LiuLiChang");
        address.add("ShenZhen HongShuLin");
        builder.addAllAddress(address);
        return builder.build();
    }

    @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) {
        cause.printStackTrace();
        ctx.close();
    }
}

注意到,使用Netty的protobuf开发客户端和服务端,主要是在代码里面用了几个特殊的编解码器,这里不细说这些编解码器的作用,可以参见对应的JAVA DOC。

Netty还提供了很多其他的编解码器,对很多种序列化方式提供支持,都在io.netty.handler.codec包下。

Protobuf使用注意事项:

ProtobufDecoder仅仅负责解码,不能读半包。需要在解码前处理半包消息,有三种方式:

1、使用ProtobufVarint32FrameDecoder

2、继承通用半包处理器LengthFieldBasedFrameDecoder

3、继承ByteToMessageDecoder自己处理半包

总结:

这篇文章,从Java序列化讲到Netty序列化的支持,以Protobuf为例演示了代码。

学完后,掌握了Netty的protobuf编程。

完整代码参见

猜你喜欢

转载自blog.csdn.net/jinxin70/article/details/86618135