protobuf在idea中的配置
首先需要下载protoc.exe文件,随后打开idea,点击setting找到Plugins,下载如下两个插件
下载安装完成后重启idea,点击Tools->Configure Genprotobuf
protoc path定位到下载的protoc.exe解析器的位置,将Quick Gen选中java并勾选下面的java
编写代码并测试
定义demo.proto文件
syntax = "proto3";
package MONITOR;
import "google/protobuf/any.proto";
enum ESensorType
{
E_VRTRIX = 0;
E_MYO = 1;
E_VHAND = 2;
E_MOCAP = 3;
E_POSITION = 4;
}
enum ECmdType
{
E_CMD_TrainInit = 0;
E_CMD_LHandTPose = 1;
E_CMD_LHandVibrate = 2;
E_CMD_RHandTPose = 3;
E_CMD_RHandVibrate = 4;
E_CMD_MocapTPose = 5;
E_CMD_MocapShutDown = 6;
E_CMD_OnlineUsrList = 7;
E_CMD_OnlineDeviceList = 8;
}
message SensorStrategy
{
bool bUse = 1;
bool bLocal = 2;
}
message Strategy
{
repeated SensorStrategy sensor = 1;
}
message User
{
uint32 nDeviceId = 1;
uint32 nUsrId = 2;
Strategy usrStrat = 3;
}
message TrainParams
{
repeated User usr = 1;
uint64 nBaseTimeMs = 2;
}
message OnlineUser
{
repeated uint32 nOnlineUserId = 1;
}
message OnlineDevice
{
repeated uint32 nOnlineDeviceId = 1;
}
message COMMAND
{
uint32 nToken = 1;
uint32 nCode = 2;
ECmdType eType = 3;
google.protobuf.Any param = 4;
}
message DATA
{
fixed32 nDataLen = 1;
uint64 nSendTime = 2;
google.protobuf.Any data = 3;
}
该proto文件包含了任意类Any,枚举类型以及数组类型repeated等使用,随后选中该proto文件,右键点击quick gen protobuf here则会生成demo.java文件。
最后编写测试类,验证是否可以通过demo.java实现数据的序列化和反序列化。
public static void main(String[] args) {
Monitor.SensorStrategy.Builder sensorStrategyBuilder1 = Monitor.SensorStrategy.newBuilder();
sensorStrategyBuilder1.setBUse(true).setBLocal(false);
Monitor.SensorStrategy.Builder sensorStrategyBuilder2 = Monitor.SensorStrategy.newBuilder();
sensorStrategyBuilder2.setBUse(true).setBLocal(true);
Monitor.SensorStrategy.Builder sensorStrategyBuilder3 = Monitor.SensorStrategy.newBuilder();
sensorStrategyBuilder3.setBUse(false);
Monitor.SensorStrategy.Builder sensorStrategyBuilder4 = Monitor.SensorStrategy.newBuilder();
sensorStrategyBuilder4.setBUse(true).setBLocal(true);
Monitor.Strategy.Builder strategyBuilder = Monitor.Strategy.newBuilder();
strategyBuilder.addSensor(0,sensorStrategyBuilder2);
strategyBuilder.addSensor(1,sensorStrategyBuilder3);
strategyBuilder.addSensor(2,sensorStrategyBuilder1);
strategyBuilder.addSensor(3,sensorStrategyBuilder4);
Monitor.User.Builder userBuilder = Monitor.User.newBuilder();
userBuilder.setNDeviceId(1).setNUsrId(7).setUsrStrat(strategyBuilder);
Monitor.TrainParams.Builder trainBuilder = Monitor.TrainParams.newBuilder();
trainBuilder.addUsr(userBuilder).setNBaseTimeMs(5000);
Monitor.COMMAND.Builder commandBuilder = Monitor.COMMAND.newBuilder();
commandBuilder.setNToken(5454).setNCode(0x01).setEType(E_CMD_TrainInit).setParam(Any.pack(trainBuilder.build()));
Monitor.DATA.Builder dataBuilder = Monitor.DATA.newBuilder();
dataBuilder.setNSendTime(CommonUtils.getTimeStamp());
//设值的时候数据长度放在最后!!!因为会变化
dataBuilder.setData(Any.pack(commandBuilder.build())).setNSendTime(10000).setNDataLen(dataBuilder.build().toByteArray().length);
//序列化发送
byte[] bytes = dataBuilder.build().toByteArray();
System.out.println("序列化后的数据:" + Arrays.toString(bytes)+",字节个数:"+bytes.length);
//5.反序列化
try {
//创建UDP客户端
DatagramSocket socket = new DatagramSocket();
//创建数据发送包
DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.58.253"),15682);
//消息发送
while (true) {
Thread.sleep(2000);
socket.send(packet);
Monitor.DATA parseFrom = Monitor.DATA.parseFrom(bytes);
System.out.println("DATA.nDataLen= "+ parseFrom.getNDataLen());
System.out.println("DATA.nSendTime= "+ parseFrom.getNSendTime());
Monitor.COMMAND unpackCommand = parseFrom.getData().unpack(Monitor.COMMAND.class);
System.out.println("COMMAND.nCode= "+unpackCommand.getNCode());
System.out.println("COMMAND.eType= "+unpackCommand.getEType());
System.out.println("COMMAND.nToken= "+unpackCommand.getNToken());
Monitor.TrainParams unpackTrain = unpackCommand.getParam().unpack(Monitor.TrainParams.class);
System.out.println("u"+unpackTrain.getNBaseTimeMs());
}
} catch (Exception e) {
e.printStackTrace();
}
}
最终测试结果如下: