httpプロトコルに基づいてprotobufを使用して前後のインタラクションを行う

4870 ワード

protobuf紹介
ネット上ではprotobufのインタラクションに関する資料がばらばらなので、protobufの前後のインタラクションに関する資料を自分で整理して参考にしました.
Google Protocol BuffersはProtobufと略称し、構造データを柔軟、効率的、自動シーケンス化するメカニズムを提供し、XMLを連想することができるが、XMLより小さく、より速く、より簡単である.必要なデータフォーマットを一度カスタマイズするだけで、Protobufコンパイラを使用して様々な言語のソースコードを自動的に生成し、ユーザーがカスタマイズしたフォーマットされたデータを読み書きすることができます.言語に関係なく、プラットフォームに関係なく、元のデータフォーマットを破壊しない上で、古いデータフォーマットに基づいて、既存のデータフォーマットを更新することもできます.
ぜんごたんインタラクションほうしき
前後端はいずれもバイナリ形式でインタラクティブな情報である.前後端にproto接尾辞のファイルを定義し、このファイルをドキュメントとしてコミュニケーションします.
protobufファイル形式
以下protobufファイルのdemo,test.proto、ファイルの構造は確かに簡単明瞭です.
enum FOO {
  BAR = 1;
}

message Test {
  required float num  = 1;
  required string payload = 2;
  optional string payloads = 3;
}

message AnotherOne {
  repeated FOO list = 1;
}

protobufの環境インストールを前後端で行う
バックエンドはnodeを例にとります:bufferhelperとprotocol-buffersをインストールしてprotobufファイルを解析します
npm install bufferhelper
npm install protocol-buffers

フロントエンドには解析protobufをインストールする環境が必要です.macはbrewを使用してprotobuf環境をインストールします.この操作には、まずHomebrew環境をインストールする必要があります.具体的なHomebrewのインストールは自分で検索します.Windowsのフロントエンド環境のインストールが少し違うので、自分で検索します.
brew install protobuf

フロントエンドproto環境がインストールされているかどうかをテストし、バージョンがあればインストールされます.
protoc --version

フロントエンドは、フロントエンドが前後のインタラクションを行う前にprotoファイルをコンパイルする必要があります.test.protoは、フロントエンドとバックエンドが同じprotoファイルです.jsファイルにコンパイルしてから実行します.まずnodeプロジェクトのprotoのディレクトリの下に入り、次のコマンドを実行するとtest_が生成されます.pb.jsファイル.最後にjsはこのファイルを解析するだけでよい.フロントエンドもこのような操作を実行する必要があります.こちらは前後端が分離しているからです.2つのプロジェクトなので、両方のプロジェクトをコンパイルする必要があります.
protoc --js_out=import_style=commonjs,binary:. test.proto

バックエンドからフロントエンドへのデータ転送
バックエンドにprotoファイルの内容を割り当て、フロントエンドに伝えます.バックエンドはprotobufバイナリをフロントエンドに渡し、先にjsonに変換してからフロントエンドに渡すことができます.そうでないと先端が文字化けしてしまいます.フロントエンドでは、このルーティングを要求する必要があります.
app.get('/proto/get', function (req, res) {
  let protobuf = require('protocol-buffers')
  let messages=protobuf(fs.readFileSync('./proto/test.proto')
  let buf = messages.Test.encode({
    num: 42,
    payload: 'hello world node js and javahhh   ',
    payloads: ''
  })
  console.log(buf) //           
  res.send(JSON.stringify(buf)); //    json      。                
})

フロントエンドは、受信バイナリストリームを先にprotoに導入する必要がある.jsファイルおよびprotobufjsプラグイン
  import awesome from '../../proto/test_pb.js'

フロントエンドはaxiosリクエスト/proto/getのルーティングで、コールバック関数のres.dataはバックエンドの戻り値です.以下の操作を行います.印刷されたmessage 3も解析されたファイルです.
 axios({
      method:'get',
      url: '/proto/get',
      headers: { 'contentType':'application/x-protobuf'} }).then(res => {
      let message3 = awesome.Test.deserializeBinary(res.data.data)
      let nums = message3.getNum()
      console.log(nums) // nums=42。            42
      let pm = awesome.Test.deserializeBinary(res.data.data)
      let protoBuf = pm.toObject()
      console.log('protoBuf: ', protoBuf) //          
    }).catch((error) => {
      console.log(error)
    })

フロントエンドからバックエンドへのデータ転送
フロントエンドはprotoファイルの割り当てとバックエンドに依存するファイルを導入するためにバイナリに変換する必要があります.
  import awesome from '../../proto/test_pb.js'
  import protobuf from 'protobufjs'
     let message = new awesome.Test() //   Person       
    //   
    message.setNum(23)
    message.setPayload('asd')
    //    
    let bytes = message.serializeBinary() //     
    let blob = new Blob([bytes], {type: 'buffer'});
    axios({
      method:'post',
      url: '/proto/send',
      data: blob,
      headers: {
        'Content-Type': 'application/octet-stream' //              ,          application/octet-stream (    )
      }
    }).then(res => {
      console.log(res)
    }).catch((error) => {
      console.log(error)
    })

バックエンドはファイル導入ファイルを受け入れる必要があります
let BufferHelper = require('bufferhelper');

バイトストリームを受信するコード
app.post('/proto/send', function (req, res) {
  let bufferHelper = new BufferHelper();
  req.on("data", function (chunk) {
    bufferHelper.concat(chunk);
  });
  req.on('end', function () {
    let protobuf = require('protocol-buffers')
    let buffer = bufferHelper.toBuffer();
    console.log(buffer) //             
    let message3 = awesome.Test.deserializeBinary(buffer)
    console.log(message3.getNum()) //          23
    let pm = awesome.Test.deserializeBinary(buffer)
    let protoBuf = pm.toObject()
    console.log(protoBuf) //     { num: 23, payload: 'asd', payloads: 'asds' }
    console.log(protoBuf.num) //   23
  });
})

以上protobufの前後インタラクションについてです.間違いがあれば指摘してください.