web中基于Protobuf的简明通信实例
Google Protocol Buffer的呈现已经有些年头了,目前Google官方提供了现今「java、php、js、go...」常用编程语言的API类库。本文通过web端js与处事器端php的交互,基于protobuf来实现简单的通信。流程图
编译器protoc的安装
https://github.com/google/protobuf/releases按照开发环境,下载相应的版本;
1.当地mac端,可直接通过brew 进行安装:$ brew install protobuf2.处事器端(linux环境):wget https://github.com/google/protobuf/releases/download/v3.5.1/protobuf-php-3.5.1.tar.gz
tar -xzf protobuf-php-3.5.1.tar.gz
cd protobuf-php-3.5.1/
./configure
make && make install查抄是否安装成功:
$ protoc --version编写test.proto文件
syntax = ”proto3”;
package lm;
message test
{
int32 id = 1;
string str = 2;
int32 opt = 3;
}编译test.proto文件
1.生成js包,有两种方式:Closure imports和 CommonJS imports
参考google/protobuf 本文使用CommonJS imports方式
$ protoc --js_out=import_style=commonjs,binary:./ test.proto命令运行后,当前文件夹会生成 test_pb.js 文件,但是此文件直接在网页中引用会报错,需要做如下工作「提示:当地环境需配置npm、browserify」:
$ npm install google-protobuf// test_pb.js中需要引入google-protobuf.js
$ browserify test_pb.js -o build.js // 生成 打包之后的文件生成的 build.js 文件,就可以在网页中直接使用了。
2.生成php包$ protoc --php_out=./ test.proto即可生成相应的php类库 test.php 文件
对于php的协议,官方也提供了两种运行方式,纯php编写的类库包和c扩展实现,两者运行方式无差异,任选一种都行。
参考 google/protobufsudo composer require google/protobuf //通过composer方式,安装纯php编写的类库包或
sudo pecl install protobuf //通过pecl,安装c扩展实现通信实现
前端 code<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8”>
<meta name=”viewport” content=”width=device-width, initial-scale=1, shrink-to-fit=no”>
<title>App</title>
<script src=”https://cdn.bootcss.com/jquery/2.2.2/jquery.min.js”></script>
</head>
<body>
<div id=”root”></div>
<!-- 引入生成的js包文件 -->
<script src=”build.js”></script>
<script>
var test = new proto.lm.test();
test.setId(10);
test.setStr('hello world');
test.setOpt(200);
var str = test.serializeBinary();
var formData = new FormData();
formData.append('data', str);
$.ajax({
url: 'http://localhost/index.php',
type: 'post',
processData: false,
contentType: false,
data: formData,
success: function (result) {
var res = result.split(”,”);
var x = new Uint8Array(res);
var data = proto.lm.test.deserializeBinary(x);
console.log(data.getStr());
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus + ”---” + errorThrown);
}
});
</script>
</body>
</html>后端 codeinclude 'vendor/autoload.php'; //如果使用c扩展的话,这个可省略了
include 'Lm/test.php'; //引入生成包文件
include 'GPBMetadata/Test.php';
$data = $_POST; //获取请求
$from = new \Lm\test();
$req = explode(”,”, $data['data']);
$str = '';
foreach($req as $value){
$str .= pack(”C”, intval($value));
}
$from->mergeFromString($str);
$str = $from->getStr();
$to = new \Lm\test();
$to->setId(10);
$to->setStr('server message, client:'.$str);
$to->setOpt(2900);
$data = $to->serializeToString();
$data = unpack(”C*”, $data);
echo implode(”,”, $data);
exit;番外网上讨论的此外 一种实现方式,如下:
//php端
$to = new \Lm\test();
$to->setStr('test string');
$data = $to->serializeToString();
$data = base64_encode($data); //通过base64编码
exit($data);
//js端
$.post(”http://localhost/index.php”, function(result){
var data = proto.lm.test.deserializeBinary(result);//客户端可直接解析base64编码
console.log(data.getStr());
});常见问题
1. ubuntu下编译protobuf 呈现protoc: error while loading shared libraries: libprotoc.so.8: cannot open shared,解决方式参考:2.PHP中pack、unpack的详细用法,参考:
页:
[1]