一看看懂Protocol Buffer(協議篇)


前言

由於筆者業團隊的業務對即時通訊服務有很大的依賴,春節結束后的第一天,紅包沒到,產品同學先到了,產品同學和我說要做一款IM,看到需求文檔后和設計圖后筆者大吃一斤

這不就是一個翻版的web qq嗎?

可以可以

聯想到最最近美團的大象,頭條的Lark,用戶與用戶,商家與用戶,企業同事的溝通,及其衍生的配套增值服務,真是需求旺盛的強需求啊

如果我要做一個WebIM應用

現在的Web應用通常會考慮ajax輪詢或者是long polling的方式來實現,但是頻繁的建立https連接,會帶來多余請求和消息精准性的問題,本質上是TCP,消息邊界不清晰,會有黏包的情況

類似我司ios和andorid客戶端,采用socket+PB協議來解決及時通訊問題,采用socket服務,依賴google的oc PB協議包來實現,socket是基於TCP協議,由通信協議和編程API組成的,原理一次HTTP協議握手成功后,與服務器建立雙向連接,數據就可以直接從TCP 通道傳輸基於事件的方式,二級制傳輸,反編譯為json或者xml

筆者在查閱翻google PB開發者文檔時,看到17年下半年google發布了官方的js的版本,配合websocket,可以與PB協議進行配合,在實現原理上,優於現有的ajax輪詢或者是long polling的實現方式

So,Let's rock !

Protocol Buffer是個什么東東?

Protocol Buffer是Google提供的一種數據序列化協議,下面是我從網上找到的Google官方對protobuf的定義:

Protocol Buffers 是一種輕便高效的結構化數據存儲格式,可以用於結構化數據序列化,很適合做數據存儲或 RPC 數據交換格式。它可用於通訊協議、數據存儲等領域的語言無關、平台無關、可擴展的序列化結構數據格式。

為什么是Node,為何要和Protocol Buffer打交道?

做為javascript開發者,對我們最好的數據序列化協議當然是JSON,pb協議相較於之前流行的XML更加的簡潔高效

pb屬於二進制協議,更容易解析,解析速度比文本協議有二向箔級別的壓制,so,在聊天場景下,udp傳輸明顯是優於tcp的

后台通信基本是基於二進制的,以往我們開發中用到的純文本協議是后台同學在封裝一層實現的,例如我司的服務,就維護了兩套,一套二進制的,一套http接口的,如果可以用Node打通了pb,可以將維護成本降到最低,理論上只有一套底層二級制服務

ps. 類似PB這樣的東西,還有MessagePack和Apache Thrift

說的這么熱鬧,老夫已經迫不及待了!

想必你已經說,別逼逼,show me the code,怎么好的開發都么上進呢?

好吧,Let's Rock & Roll!

官方案例

我們來操作一下

安裝google-protobuf

2017年4月開始官方支持javascript

github

develops

 

 

npm install google

  1. -protobuf

定義.proto文件

proto文件 messages.proto

  1. package zxwj;

  2. syntax = "proto3";

  3. message helloworld

  4. {

  5.   string zzuid = 123;  

  6.   string zzstatus = 0;

  7. }  

編譯.proto文件

使用protobuf.js命令行工具編譯

  1. protoc --js_out=import_style=commonjs,binary:. messages.proto

protoc會編譯輸入文件,並且構建messages_pb,在sever中,可以以以下方式引用

  1. var messages = require('./messages_pb');

  2. var message = new messages.MyMessage();

編寫server.js

  1. var basepb = require('./messages_pb');

  2. console.log(basepb);

  3.  

  4. var message = new basepb.SearchRequest();

  5. console.log(message);

  6.  

  7. message.setName("TS");

  8. message.setPassword("123456");

  9.  

  10. var bytes = message.serializeBinary(); //對象序列化

  11. console.log(bytes);

  12.  

  13. var message2 = basepb.SearchRequest.deserializeBinary(bytes); //進制序列化

  14. console.log(message2);

運行

  1. node sever.js

總結一下

上個案例並不具備線上產品能力,但是還可以能看出PB協議的優勢所在

快,從官方的測試結果來看,整體比較起來,ProtoBuf.js 則是比純JSON 的處理快上一倍以上,附官方Github測試結果(機器配置:i7-2600K。Node.js 版本:6.9.1)

  1. benchmarking encoding performance ...

  2.  

  3. Type.encode to buffer x 547,361 ops/sec ±0.27% (94 runs sampled)

  4. JSON.stringify to string x 310,848 ops/sec ±0.73% (92 runs sampled)

  5. JSON.stringify to buffer x 173,608 ops/sec ±1.51% (86 runs sampled)

  6.  

  7.      Type.encode to buffer was fastest

  8.   JSON.stringify to string was 43.5% slower

  9.   JSON.stringify to buffer was 68.7% slower

  10.  

  11. benchmarking decoding performance ...

  12.  

  13. Type.decode from buffer x 1,294,378 ops/sec ±0.86% (90 runs sampled)

  14. JSON.parse from string x 291,944 ops/sec ±0.72% (92 runs sampled)

  15. JSON.parse from buffer x 256,325 ops/sec ±1.50% (90 runs sampled)

  16.  

  17.    Type.decode from buffer was fastest

  18.     JSON.parse from string was 77.4% slower

  19.     JSON.parse from buffer was 80.3% slower

  20.  

  21. benchmarking combined performance ...

  22.  

  23. Type to/from buffer x 254,126 ops/sec ±1.13% (91 runs sampled)

  24. JSON to/from string x 122,896 ops/sec ±1.29% (90 runs sampled)

  25. JSON to/from buffer x 88,005 ops/sec ±0.87% (89 runs sampled)

  26.  

  27.        Type to/from buffer was fastest

  28.        JSON to/from string was 51.7% slower

  29.        JSON to/from buffer was 65.3% slower

  30.  

  31. benchmarking verifying performance ...

  32.  

  33. Type.verify x 6,246,765 ops/sec ±2.00% (87 runs sampled)

  34.  

  35. benchmarking message from object performance ...

  36.  

  37. Type.fromObject x 2,892,973 ops/sec ±0.70% (92 runs sampled)

  38.  

  39. benchmarking message to object performance ...

  40.  

  41. Type.toObject x 3,601,738 ops/sec ±0.72% (93 runs sampled)

接下來要做的事情

PB的優勢場景是IM中的數據存儲和交互,如果要實現一個高品質的IM,信息流的穩定和邊界很重要,我們還需要完善以下幾個部分

  • 穩定可維護的Node socket.io服務(socket篇)

  • PB的動態編譯的特性和嵌套message,數據結構簡單化(數據篇)

  • 前端對於二級制的的處理,例如ArrayBuffer,序列化與反序列化,MD5加密(加密篇)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM