websocket+protocol buffer 实战
<p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">来源:http://div.io/topic/1657</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">websocket+protocol buffer 实战</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">1.起因</h4><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">之前公司的im聊天一直是基于ajax的,先抛开轮询还是long poll不说,但是不论是页面上源源不断的ajax请求还是服务器hold长链都是很蛋疼的事情。<br>这种架子持续了一年半左右,终于在换了第n+1个产品和另一波后台技术支持的时候,机会来了,在某次新版im立项会议上串通好后台,强烈建议产品延期进行底层改造,websocket就这样开始了。</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">2.websocket和socket.io的异同</h4><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">公司有内部编辑用的socket.io项目,正好拿来和websocket做对比。当时做socket.io的时候后台用的node,你会发现,在初始化socket.io的时候参数是'<a href="http://div.io/topic/1657" style="text-decoration: none; color: rgb(49, 135, 219);">http://.....</a>'而websocket在初始化的时候用的是'ws://....',socket.io内部对websocket做了兼容处理,也就是他同时支持socket.io以及ajax,会根据不同的情境选择不同的方法来处理,而webesocket连接的时候必须使用ws协议。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">简单浏览一下sokcet.io的源码会发现如下的代码片段(图一)</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><img src="http://divio.qiniudn.com/Fv0vMLVfQSD_i9BtDX_6Wzlvzw6E" alt="socket.io源码" style="max-width: 50em; margin-top: 1em; margin-bottom: 1em;"><br>图中可以看出来,sokcet.io对几种机制分别预留了相应的api。</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">3.protocol buffer</h4><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这是是google的一种数据传输格式,体积小巧(欲知详情 <a href="https://developers.google.com/protocol-buffers" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219);">https://developers.google.com/protocol-buffers</a> )。对于我们前端开发者来说,也不过就是一个和后台预定义好的json串,具体怎么预定义,是通过一个后缀名为.proto的文件,前端在调用protocol buffer的时候会预先加载proto文件,生成相应的json串,之后只要是数据传输,用的都是这个json串,形式永远不会改变,所以我们处理起来很方便咯。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">如下图,是个超级简单的proto文件的规范(图2)</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><img src="http://divio.qiniudn.com/Fuvi0tP0YztuTSm9MNACLJzgBXq7" alt="proto文件" style="max-width: 50em; margin-top: 1em; margin-bottom: 1em;"></p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">而最终前端解析出来的json串是酱紫滴(图3)</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><img src="http://divio.qiniudn.com/Fs2HPuW20qndQco3tzNZn3Knnrb6" alt="proto解析" style="max-width: 50em; margin-top: 1em; margin-bottom: 1em;"><br>是不是炒鸡神奇(神奇你妹啊,还有炒鸡是几个意思?),接下来简单剖析一下proto和json的对应关系</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">4.protocol buffer和json</h4><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">解析这个proto其实很简单,从主要类入手,这里面主类就是Msg,Msg下面又有三个属性,以第一个为例进行解析:<br>-第一个参数required说明每次传参都要传过去;<br>-第二个参数是MsgType,这个参数指的是参数类型,而MsgType这个类型如图二所示,在开始已经定义好,枚举类型:1表示login,2表示loginAck。这时候大家再去看图三,我准备发送的消息的MsgType为1,意思就是我通知后台我要登录了,而接受到的是2,表示loginAck,也就是后台确认你已经登录。就这么简单,注册登录就已经完成了<br>-第三个参数其实就相当于我们要操作的对象的属性,也就是Msg.msgType我们就可以访问到并且修改了(这里只是举例,其实Msg需要提前实例化并调用protocol buffer内部api进行转换,形成json)</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">5.protocol buffer和websocket</h4><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">大家都了解,websocket是通过二进制进行传输的,并且在定义socket的时候会加上socket.binaryType = "arraybuffer"这句话,所以说咯,protocol buffer在json的转换中必须要来回转换为buffer才能进行数据传输,比较人性化的是protocol buffer中提供了相应的decode和toArrayBuffer方法对数据进行二进制转换。</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif;">6.尾声</h4><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: "helvetica neue", tahoma, "hiragino sans gb", stheiti, "wenquanyi micro hei", 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">该介绍的都介绍完了,开发就很easy了,sokect和protocol buffer也是可以愉快共存的朋友,开发的时候不要忘了socket的心跳和断线重连哦~<br>by 乐居小菜</p><p></p>
页:
[1]