什么是pb
是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。
我们为什么要使用
开发中我们经常做数据交换,我们常常使用json,xml来进行数据的传递,来达到一个通用性的数据。也就是说我在c++上发送一条数据给java客户端。客户端通过反序列化得到原始数据。为什么不使用json呢?因为json性能都没有pb高,而且pb支持非常多的语言。
正式安装
这里我将pb的github地址贴出来供大家下载。https://github.com/google/protobuf。
在Centos下安装
1.安装依赖库
yum install autoconf autoreconf libtool gcc-c++
2.下载最新的protobuf-master.zip
> wget https://github.com/google/protobuf/archive/master.zip
> unzip protobuf-master.zip
> cd protobuf-master
> ./autogen.sh
> ./configure
> make
> make check
> make install
3.错误提示
如果出现错误就是依赖库没有找到,由于各个系统的袭来库都不同,所以遇到问题及时百度。
4.定义消息包
msg.proto
syntax = "proto3";
message msg {
string name = 1;
int32 id = 2;
string email = 3;
}
5.编译消息包
--cpp_out=OUT_DIR Generate C++ header and source.
--csharp_out=OUT_DIR Generate C# source file.
--java_out=OUT_DIR Generate Java source file.
--javanano_out=OUT_DIR Generate Java Nano source file.
--js_out=OUT_DIR Generate JavaScript source.
--objc_out=OUT_DIR Generate Objective C header and source.
--python_out=OUT_DIR Generate Python source file.
--ruby_out=OUT_DIR Generate Ruby source file.
protoc -I=. --java_out=. msg.proto
6.生成Msg.java
具体生成的类我就不贴出来。
7.Netty+Protobuf通信
netty服务器端及客户端通道中设置protobuf编解码
ChannelPipeline pipe = socketChannel.pipeline();
pipe.addLast(new IdleStateHandler(10, 0, 0,TimeUnit.SECONDS));
pipe.addLast(new ProtobufVarint32FrameDecoder());//编码器,netty框架实现,直接实例化
pipe.addLast(new ProtobufDecoder(Msg.msg.getDefaultInstance()));//netty已实现,只需传入具体的消息实例
pipe.addLast(new ProtobufVarint32LengthFieldPrepender());//转码器,netty框架实现,直接实例化
pipe.addLast(new ProtobufEncoder());//转码器,netty框架实现,直接实例化
pipe.addLast(new NettyServerHandler());
8.接收消息
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
Msg.msg mess = (com.hengyi.msg.Msg.msg) msg;
System.out.println(mess.getReceive());
}
9.发送消息
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Msg.msg.Builder msgBuilder = Msg.msg.newBuilder();
msgBuilder.setReceive("server");
msgBuilder.setSend("client");
msgBuilder.setContent(ByteString.copyFromUtf8("你好,我是客户端"));
msgBuilder.setType(1);
msgBuilder.setExtraType(1);
msgBuilder.setVersion(1);
Msg.msg message = msgBuilder.build();
ctx.writeAndFlush(message);
}