Google Protocol Buffers 簡稱 Protobuf,它提供了一種靈活、高效、自動序列化結構數據的機制,能夠聯想 XML,可是比 XML 更小、更快、更簡單。僅須要自定義一次你所需的數據格式,而後用戶就可使用 Protobuf 編譯器自動生成各類語言的源碼,方便的讀寫用戶自定義的格式化的數據。與語言無關,與平臺無關,還能夠在不破壞原數據格式的基礎上,依據老的數據格式,更新現有的數據格式。前端
先後端都是以二進制形式進行交互信息。先後端定義proto後綴的文件,以此文件來當文檔來進行溝通。java
如下爲protobuf文件的demo,test.proto,文件的結構確實簡單明瞭。node
enum FOO {
BAR = 1;
}
message Test {
required float num = 1;
required string payload = 2;
optional string payloads = 3;
}
message AnotherOne {
repeated FOO list = 1;
}
複製代碼
後端以node爲例子: 安裝bufferhelper以及protocol-buffers進行解析protobuf文件ios
npm install bufferhelper
npm install protocol-buffers
複製代碼
前端須要安裝解析protobuf的環境。 mac使用brew安裝protobuf環境。此操做須要先安裝Homebrew環境。具體的Homebrew的安裝自行搜索。 windows的前端環境安裝有點不同,自行搜索。npm
brew install protobuf
複製代碼
測試前端proto環境是否是安裝好了,若是有版本就是安裝好了。json
protoc --version
複製代碼
在進行先後端交互以前,前端須要進行編譯proto文件。 test.proto爲前端以及後端相同的proto文件。先編譯爲js文件再執行。首先進入node項目的proto的目錄下面,執行下面的命令以後會生成test_pb.js文件。最後js只須要解析這個文件便可。前端也須要執行這樣的操做,由於我這邊是先後端分離的。是兩個項目,因此兩個項目都須要編譯。axios
protoc --js_out=import_style=commonjs,binary:. test.proto
複製代碼
後端賦值proto文件的內容並傳給前端。 後端傳protobuf二進制給前端,要先轉化爲json才能夠給前端。否則的話前端會轉化成亂碼的。前端須要請求此路由。windows
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爲後端的返回值。進行如下操做。打印出來的message3也是解析好的文件。瀏覽器
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的先後交互。若有錯誤,請指出。