Hi, all
Due to business needs, the original json transmission format was changed to protobuf. The server side uses php, and the client side is android and ios.
During the debugging process, it was found that the client could not parse the data transmitted by the server, and the android client always reported an exception, as follows:
Protobuf error:Protocol message tag had invalid wire type
Background Information
The situation on the php side
php5.4
Porobuf-php
protoc 2.4.1
Development under mac osx 10.8
Android side
Android version 4.4
The official protobuf library 2.4.1
protoc 2.4.1
ubuntu
Both PHP and Android use the same set of * .proto files to generate corresponding classes.
The php side is serialized as follows:
// use binary codec
$codec = new \DrSlump\Protobuf\Codec\Binary();
// prepare final output
$response = new \ResponseMsg();
$response->setStatusCode(\ResponseMsg\ErrorCode::RET_OK);
$response->setData($codec->encode($recommend_bras));
// Use custom codec
$data = $codec->encode($response);
echo $data;
Deserialization on Android:
byte[] bytes = ret.result.getBytes();
//ByteString byteString = ByteString.copyFromUtf8(ret.result);
PResponseMsg.ResponseMsg responseMsg = PResponseMsg.ResponseMsg.parseFrom(bytes);
Reply content:
Hi, all
Due to business needs, the original json transmission format was changed to protobuf. The server side uses php, and the client side is android and ios.
During the debugging process, it was found that the client could not parse the data transmitted by the server, and the android client always reported an exception, as follows:
Protobuf error:Protocol message tag had invalid wire type
Background Information
The situation on the php side
php5.4
Porobuf-php
protoc 2.4.1
Development under mac osx 10.8
Android side
Android version 4.4
The official protobuf library 2.4.1
protoc 2.4.1
ubuntu
Both PHP and Android use the same set of * .proto files to generate corresponding classes.
The php side is serialized as follows:
// use binary codec
$codec = new \DrSlump\Protobuf\Codec\Binary();
// prepare final output
$response = new \ResponseMsg();
$response->setStatusCode(\ResponseMsg\ErrorCode::RET_OK);
$response->setData($codec->encode($recommend_bras));
// Use custom codec
$data = $codec->encode($response);
echo $data;
Deserialization on Android:
byte[] bytes = ret.result.getBytes();
//ByteString byteString = ByteString.copyFromUtf8(ret.result);
PResponseMsg.ResponseMsg responseMsg = PResponseMsg.ResponseMsg.parseFrom(bytes);
Find a solution, and then use base64 encoding to transmit the content.
A colleague suggested using a dichotomy to find the problem, so I tried the following:
1. First store the serialized content of the server into memory, and then reverse solution, and found no problem. Preliminary conjecture may be that something went wrong during the transmission. Because the client and server are transmitted using http, there may be a problem with the content encoding format.
2. Ask the colleague on the client to help save the received content to the file system, and then compare the content on the server to confirm whether there is a coding problem. In the end, it was found that the content lengths of the two were different, and it was confirmed that something went wrong during the transmission.
3. Checked some statements on the Internet. The binary content cannot be directly transmitted in the http protocol, so it should be transmitted after base64 encoding. The client can get the anti-analysis and get the final data.
I haven't figured out why the protobuf-php library is used to serialize the content and then it will not work. It will be added ...