GCP Pub/Sub IoT Protobuf消息解码报无效WireType异常排查
问题解答
关于Pub/Sub消息Base64编码的疑问
你拿到的示例串CAEQneDs_gQaIAjK4Oz-BBIVEKA4GOzMmQEgzLPUAyjIEzD8y_4NGKBWIg0QvvACGgAogPwCMNogKgkQCRgBKOKFqR4=本身就是标准URL安全型Base64编码结果,GCP的Base64编码规则和常规逻辑没有偏差:
- 当通过REST API、控制台页面拉取Pub/Sub消息时,二进制Protobuf负载无法直接嵌入JSON文本结构,会默认被编码为Base64字符串返回
- 如果使用官方Pub/Sub客户端SDK拉取消息,SDK会自动完成Base64解码,直接返回原始二进制字节数组,不需要手动处理。很多人混淆了不同访问方式返回的数据格式,才会误以为消息没有做Base64编码。
Java解析报InvalidWireTypeException的排查方案
这个异常的本质是解析器读到的字节不符合Protobuf的二进制格式规范,结合你的场景按优先级排查即可:
- 漏做Base64解码(90%以上概率是这个原因)
如果你直接把Base64字符串的字节(也就是调用string.getBytes()拿到的ASCII字节)传给parseFrom()方法,相当于把Base64文本当成Protobuf二进制解析,必然触发wire类型错误。你用的在线Protobuf解码工具默认会先把输入做Base64解码再解析Protobuf,所以能正常出结果。
正确处理代码示例:import java.util.Base64; // GCP返回的是URL安全变体Base64,要用对应解码器 byte[] rawProtoBytes = Base64.getUrlDecoder().decode(pubsubMessageDataStr); MqttWeatherPayload payload = MqttWeatherPayload.parseFrom(rawProtoBytes); - Protobuf定义不匹配
你贴出的proto文件存在明显的定义缺失和不匹配问题:- 根消息
MqttPayload中引用的SensorData类型没有定义,仅定义了WeatherData、WeatherSensorData类型 PhysicalStatus消息中引用的GPSPos、GPSStatus类型没有给出定义- 异常栈中你调用的是
MqttWeatherPayload类的解析方法,但你贴出的根消息名为MqttPayload,需要确认代码中使用的proto生成类,和设备端序列化时用的proto版本、字段编号、字段类型完全一致,任意不匹配都可能触发wire类型错误。
- 根消息
- 解析数据源错误
如果你是从Cloud IoT Core转发消息到Pub/Sub,注意不要把Pub/Sub返回的整条JSON消息(包含messageId、publishTime、attributes等元数据字段)直接当成负载解析,必须先提取JSON结构中data字段的内容再做解码解析。
内容的提问来源于stack exchange,提问作者Duje Drobac
相关产品推荐
相关产品推荐

