⼀看看懂ProtocolBuffer(协议篇)
前⾔
由于笔者业团队的业务对即时通讯服务有很⼤的依赖,春节结束后的第⼀天,红包没到,产品同学先到了,产品同学和我说要做⼀款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);
thrift
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. de 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.      de 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. Object x 3,601,738 ops/sec ±0.72% (93 runs sampled)
接下来要做的事情
PB的优势场景是IM中的数据存储和交互,如果要实现⼀个⾼品质的IM,信息流的稳定和边界很重要,我们还需要完善以下⼏个部分
稳定可维护的Node socket.io服务(socket篇)
PB的动态编译的特性和嵌套message,数据结构简单化(数据篇)
前端对于⼆级制的的处理,例如ArrayBuffer,序列化与反序列化,MD5加密(加密篇)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。