加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱资讯网 (https://www.52junxun.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

web中基于Protobuf的简明通信实例

发布时间:2022-12-19 11:46:19 所属栏目:PHP教程 来源:
导读:  Google Protocol Buffer的出现已经有些年头了,目前Google官方提供了现今「java、php、js、go...」常用编程语言的API类库。本文通过web端js与服务器端php的交互php交互,基于protobuf来实现简单的通信。

  
  Google Protocol Buffer的出现已经有些年头了,目前Google官方提供了现今「java、php、js、go...」常用编程语言的API类库。本文通过web端js与服务器端php的交互php交互,基于protobuf来实现简单的通信。

  流程图编译器protoc的安装github.com/google/protobuf/releases
 
  根据开发环境,下载相应的版本;
 
  1.本地mac端,可直接通过brew 进行安装:
 
  $ brew install protobuf
  2.服务器端(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/protobuf
 
  sudo 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>
      
      <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>
  后端 code
 
  include '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());
  });
 

(编辑:我爱资讯网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!