因爲筆者業團隊的業務對即時通信服務有很大的依賴,春節結束後的第一天,紅包沒到,產品同窗先到了,產品同窗和我說要作一款IM,看到需求文檔後和設計圖後筆者大吃一斤javascript
這不就是一個翻版的web qq嗎?前端
能夠能夠java
聯想到最最近美團的大象,頭條的Lark,用戶與用戶,商家與用戶,企業同事的溝通,及其衍生的配套增值服務,真是需求旺盛的強需求啊node
如今的Web應用一般會考慮ajax輪詢或者是long polling的方式來實現,可是頻繁的創建https鏈接,會帶來多餘請求和消息精準性的問題,本質上是TCP,消息邊界不清晰,會有黏包的狀況ios
相似我司ios和andorid客戶端,採用socket+PB協議來解決及時通信問題,採用socket服務,依賴google的oc PB協議包來實現,socket是基於TCP協議,由通訊協議和編程API組成的,原理一次HTTP協議握手成功後,與服務器創建雙向鏈接,數據就能夠直接從TCP 通道傳輸基於事件的方式,二級制傳輸,反編譯爲json或者xmlgit
筆者在查閱翻google PB開發者文檔時,看到17年下半年google發佈了官方的js的版本,配合websocket,能夠與PB協議進行配合,在實現原理上,優於現有的ajax輪詢或者是long polling的實現方式github
So,Let's rock !web
Protocol Buffer是Google提供的一種數據序列化協議,下面是我從網上找到的Google官方對protobuf的定義:ajax
Protocol Buffers 是一種輕便高效的結構化數據存儲格式,能夠用於結構化數據序列化,很適合作數據存儲或 RPC 數據交換格式。它可用於通信協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。npm
作爲javascript開發者,對咱們最好的數據序列化協議固然是JSON,pb協議相較於以前流行的XML更加的簡潔高效
pb屬於二進制協議,更容易解析,解析速度比文本協議有二向箔級別的壓制,so,在聊天場景下,udp傳輸明顯是優於tcp的
後臺通訊基本是基於二進制的,以往咱們開發中用到的純文本協議是後臺同窗在封裝一層實現的,例如我司的服務,就維護了兩套,一套二進制的,一套http接口的,若是能夠用Node打通了pb,能夠將維護成本降到最低,理論上只有一套底層二級制服務
ps. 相似PB這樣的東西,還有MessagePack和Apache Thrift
說的這麼熱鬧,老夫已經火燒眉毛了!
想必你已經說,別逼逼,show me the code,怎麼好的開發都麼上進呢?
好吧,Let's Rock & Roll!
咱們來操做一下
2017年4月開始官方支持javascript
github
develops
npm install google
-protobuf
proto文件 messages.proto
package zxwj;
syntax = "proto3";
message helloworld
{
string zzuid = 123;
string zzstatus = 0;
}
使用protobuf.js命令行工具編譯
protoc --js_out=import_style=commonjs,binary:. messages.proto
protoc會編譯輸入文件,而且構建messages_pb,在sever中,能夠以如下方式引用
var messages = require('./messages_pb');
var message = new messages.MyMessage();
var basepb = require('./messages_pb');
console.log(basepb);
var message = new basepb.SearchRequest();
console.log(message);
message.setName("TS");
message.setPassword("123456");
var bytes = message.serializeBinary(); //對象序列化
console.log(bytes);
var message2 = basepb.SearchRequest.deserializeBinary(bytes); //進制序列化
console.log(message2);
node sever.js
快,從官方的測試結果來看,總體比較起來,ProtoBuf.js 則是比純JSON 的處理快上一倍以上,附官方Github測試結果(機器配置:i7-2600K。Node.js 版本:6.9.1)
benchmarking encoding performance ...
Type.encode to buffer x 547,361 ops/sec ±0.27% (94 runs sampled)
JSON.stringify to string x 310,848 ops/sec ±0.73% (92 runs sampled)
JSON.stringify to buffer x 173,608 ops/sec ±1.51% (86 runs sampled)
Type.encode to buffer was fastest
JSON.stringify to string was 43.5% slower
JSON.stringify to buffer was 68.7% slower
benchmarking decoding performance ...
Type.decode from buffer x 1,294,378 ops/sec ±0.86% (90 runs sampled)
JSON.parse from string x 291,944 ops/sec ±0.72% (92 runs sampled)
JSON.parse from buffer x 256,325 ops/sec ±1.50% (90 runs sampled)
Type.decode from buffer was fastest
JSON.parse from string was 77.4% slower
JSON.parse from buffer was 80.3% slower
benchmarking combined performance ...
Type to/from buffer x 254,126 ops/sec ±1.13% (91 runs sampled)
JSON to/from string x 122,896 ops/sec ±1.29% (90 runs sampled)
JSON to/from buffer x 88,005 ops/sec ±0.87% (89 runs sampled)
Type to/from buffer was fastest
JSON to/from string was 51.7% slower
JSON to/from buffer was 65.3% slower
benchmarking verifying performance ...
Type.verify x 6,246,765 ops/sec ±2.00% (87 runs sampled)
benchmarking message from object performance ...
Type.fromObject x 2,892,973 ops/sec ±0.70% (92 runs sampled)
benchmarking message to object performance ...
Type.toObject x 3,601,738 ops/sec ±0.72% (93 runs sampled)
PB的優點場景是IM中的數據存儲和交互,若是要實現一個高品質的IM,信息流的穩定和邊界很重要,咱們還須要完善如下幾個部分
穩定可維護的Node socket.io服務(socket篇)
PB的動態編譯的特性和嵌套message,數據結構簡單化(數據篇)
前端對於二級制的的處理,例如ArrayBuffer,序列化與反序列化,MD5加密(加密篇)