登录  /  注册

用protobuf数据格式,报“Protocol message tag had invalid wire type”异常

php中文网
发布: 2016-06-06 20:42:36
原创
9137人浏览过

hi,all

因为业务需要,把原本的json的传输格式改成protobuf。服务端这边用的是php,客户端那边是android和ios。

在调试的过程中,发现客户端一直不能解析服务端传输过去的数据,android客户端一直报异常,如下:

<code>Protobuf error:Protocol message tag had invalid wire type
</code>
登录后复制
登录后复制

背景信息

php端这边的情况

  • php5.4
  • Porobuf-php
  • protoc 2.4.1
  • mac osx 10.8下开发

Android端

  • Android版本4.4
  • 官方的protobuf库 2.4.1
  • protoc 2.4.1
  • ubuntu

php和android都是用同一套*.proto文件去生成对应的类。

php这边是如下序列化的:

<code>    // use binary codec
    $codec = new \DrSlump\Protobuf\Codec\Binary();

    // prepare final output
    $response = new \ResponseMsg();
    $response-&gt;setStatusCode(\ResponseMsg\ErrorCode::RET_OK);
    $response-&gt;setData($codec-&gt;encode($recommend_bras));

    // Use custom codec
    $data = $codec-&gt;encode($response);
    echo $data;
</code>
登录后复制
登录后复制

Android端的反序列化:

<code> byte[] bytes = ret.result.getBytes();

//ByteString byteString = ByteString.copyFromUtf8(ret.result);

PResponseMsg.ResponseMsg responseMsg = PResponseMsg.ResponseMsg.parseFrom(bytes); 
</code>
登录后复制
登录后复制

回复内容:

hi,all

因为业务需要,把原本的json的传输格式改成protobuf。服务端这边用的是php,客户端那边是android和ios。

在调试的过程中,发现客户端一直不能解析服务端传输过去的数据,android客户端一直报异常,如下:

<code>Protobuf error:Protocol message tag had invalid wire type
</code>
登录后复制
登录后复制

背景信息

php端这边的情况

  • php5.4
  • Porobuf-php
  • protoc 2.4.1
  • mac osx 10.8下开发

Android端

  • Android版本4.4
  • 官方的protobuf库 2.4.1
  • protoc 2.4.1
  • ubuntu

php和android都是用同一套*.proto文件去生成对应的类。

php这边是如下序列化的:

<code>    // use binary codec
    $codec = new \DrSlump\Protobuf\Codec\Binary();

    // prepare final output
    $response = new \ResponseMsg();
    $response-&gt;setStatusCode(\ResponseMsg\ErrorCode::RET_OK);
    $response-&gt;setData($codec-&gt;encode($recommend_bras));

    // Use custom codec
    $data = $codec-&gt;encode($response);
    echo $data;
</code>
登录后复制
登录后复制

Android端的反序列化:

<code> byte[] bytes = ret.result.getBytes();

//ByteString byteString = ByteString.copyFromUtf8(ret.result);

PResponseMsg.ResponseMsg responseMsg = PResponseMsg.ResponseMsg.parseFrom(bytes); 
</code>
登录后复制
登录后复制

找到解决方法了,把传输的内容用base64编码再传输就可以了。

同事提示用二分法去查找问题,所以我做了下面的尝试:

1、先把服务器序列化后的内容存到内存,然后反解,发现没问题。初步猜想可能是内容在传输的过程中出了问题。因为客户端和服务端之间是用http传输的,可能是内容编码格式有问题。
2、让客户端的同事帮忙把收到的内容存到文件系统,然后对比服务端的内容,确认是不是存在编码问题。最后发现,两者的内容长度不一样,确认是传输过程中出了问题。
3、查了下网上的一些说法,二进制的内容不能直接在http协议传输,于是该用base64编码之后再传输出去,客户端拿到再反解,能拿到最后的数据了。

暂时还没想到为什么用protobuf-php库把内容序列化后,再传输为什么会不行,待补充......

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
关于CSS思维导图的课件在哪? 课件
凡人来自于2024-04-16 10:10:18
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号