Protocol Buffers是Google推出的一个数据交换格式,相对于xml它的体积更小,更快,因为它是二进制传输的。3.0相对于2.0变动比较大。这些变动可以去看官方说明。

在前端使用ProtoBuf.js解析.proto文件,先需要再界面上引入protobuf.js。

定义一个.proto

syntax = "proto3";
// Token
message MyModel{
string UserID = ;
string Device = ;
}
message Message{
string ChannelID = ;
bytes Content = ;
}

加载:

protobuf.load("Models.proto", function (err, root) {
if (err)
throw err;
console.log(root);
var MyModel = root.lookupType("MyModel");
console.log(MyModel);
});

Root包含了我们定义的两个模型。拿到这个模型就可以用来发送消息和解析消息了。注意到我们的上面的Message的Content是bytes类型。JavaScript本身是没有这个类型的。

根据protobuf.js的官方说明可以通过base64编码来实现:

function base64Encode(input) {
var rv;
rv = encodeURIComponent(input);
rv = unescape(rv);
rv = window.btoa(rv);
return rv;
}
 var buffer1 = base64Encode("消息");
console.log(buffer1);
var model = { ChannelID: "12121", Content: buffer1 };
var message = Message.create(model);//创建模型
var buffer = Message.encode(message).finish();//转成二进制
console.log(buffer);

运行页面,对象已经被转化了数组

这个时候可以用的WebSocket的send方法将对象发送到后端,但还可以根据和后端约定的协议对消息再做一次转换。

解析:

  var decodeModel = Message.decode(buffer);
console.log(decodeModel);
console.log(Ut8ArrayToStr(decodeModel.Content));

拿到buffer之后再次转化成我们的对象

这个时候需要将Uint8Array转成字符串,才能直观的获得我们的Content中的内容。

function Ut8ArrayToStr(array) {
var out, i, len, c;
var char2, char3; out = "";
len = array.length;
i = 0;
while (i < len) {
c = array[i++];
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}

这样就完成整个过程。

小结:

实际开发中比上面介绍的要复杂,首先加载.proto对象是异步的,也就是说,在你使用WebSocket收发送消息的时候要确保已经获得了模型,也就是例子中的Message对象。另外一个是兼容性处理。protobuf.js的兼容性如下:

比如ie8不支持,当然我们也不是要在IE8中使用protobuf.js,因为ie8也不支持WebSocket,我们可以用轮询。是为了避免引入protobuf.js就会报错,毕竟这个js有很多新浏览器对象。可以用typeof来阻止它在不支持的浏览器中运行。

//不支持WebSocket的 就不用初始化了
if (!window.WebSocket) return;
if (typeof exports=="undefined") return ;
exports.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE);

同理,自己的js中也要判断。

    function loadProto() {
if (typeof protobuf == "undefined") return;//说明浏览器加载失败
protobuf.load("../xx.proto", function (err, root) {

这样如果你有备用的轮询通信方式,在ie8中也能运行起来了。

另外,Google官方也提供了JavaScript解析.proto文件的方式。

1. CommonJS-style imports (eg. `var protos = require('my-protos');`)
2. Closure-style imports (eg. `goog.require('my.package.MyProto');`)

closure-style的需要依赖goog,一大堆,而commonjs的示例更像是在node端的,在这个地方绕了一天,没成功,最后选择了protobuf.js的方式。

websoket使用Protocol Buffers3.0传输的更多相关文章

  1. Hyper Text Transfer Protocol(超文本传输协议)

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...

  2. USB 3.0传输规格

    通用序列总线(USB) 从1996问世以来,一统个人电脑外部连接界面,且延伸至各式消费性产品,早已成为现代人生活的一部分.2000年发表的USB 2.0 High-speed规格,提供了480Mbps ...

  3. 新一代的USB 3.0传输规格

    通用序列总线(USB) 从1996问世以来,一统个人电脑外部连接界面,且延伸至各式消费性产品,早已成为现代人生活的一部分.2000年发表的USB 2.0 High-speed规格,提供了480Mbps ...

  4. Protocol Buffer格式传输

    1.简单明了介绍ProtocolBuffer 2. ProtocolBuffer(pb)所做事情其实类似于xml.json,也就是把某种数据结构的信息依照某种格式保存起来.主要用于数据存储.传输等. ...

  5. TLS 改变密码标准协议(Change Cipher Spec Protocol) 就是加密传输中每隔一段时间必须改变其加解密参数的协议

    SSL修改密文协议的设计目的是为了保障SSL传输过程的安全性,因为SSL协议要求客户端或服务器端每隔一段时间必须改变其加解密参数.当某一方要改变其加解密参数时,就发送一个简单的消息通知对方下一个要传送 ...

  6. TFTP(Trivial File Transfer Protocol,简单文件传输协议)

    网络特性 通常使用UDP 69端口(据说可改成TCP) 与FTP区别 轻量级,适用于传输小文件,当然功能也少些,比如没有列出目录功能,不进行认证

  7. MTP(Media Transfer Protocol(媒体传输协议))简介

    ---恢复内容开始--- 1,简单说明 MTP,微软公司规定的新的传输规则(字面本来应该是协议的,但是自己感觉更像是规则,制定了基本上的所有路线,剩下的是你想怎么选择罢了,使用者完全没有可能在它的框架 ...

  8. HTTP(HyperText Transport Protocol)超文本传输协议的状态码

    关于HTTP状态码:是用于表示网页服务器HTTP响应状态的3位数字代码. 所有状态码的第一个数字代表了响应的五种状态之一. 1xx:消息:这一类型的状态码代表请求已被接受,需要继续处理 2xx:成功: ...

  9. WebSocket 学习(三)--用nodejs搭建服务器

    前面已经学习了WebSocket API,包括事件.方法和属性.详情:WebSocket(二)--API  WebSocket是基于事件驱动,支持全双工通信.下面通过三个简单例子体验一下. 简单开始 ...

随机推荐

  1. 使用es6特性封装async-mysql

    node.js的mysql模块本身没有提供返回promise的函数,即是说都是用的回调函数,那么对于我们使用async函数是很不方便的一件事.node.js有一个mysql封装库叫mysql-prom ...

  2. Lucas定理学习(进阶中)

    (1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 =  [n/p]*p+a0,m=[m/p]*p+b0其次,我们 ...

  3. yolov2训练ICDAR2011数据集

    首先下载数据集train-textloc.zip 其groundtruth文件如下所示: 158,128,412,182,"Footpath" 442,128,501,170,&q ...

  4. java学习笔记 --- 条件,循环语句

    一.三元运算符 A:格式    比较表达式?表达式1:表达式2;   B:执行流程:    首先计算比较表达式的值,看是true还是false.    如果是true,表达式1就是结果.    如果是 ...

  5. Unity 3D Framework Designing(5)——ViewModel之间如何共享数据

    对于客户端应用程序而言,单页应用程序(Single Page Application)是最常见的表现形式.有经验的开发人员往往会把一个View分解多个SubView.那么,如何在多个SubView之间 ...

  6. 《连载 | 物联网框架ServerSuperIO教程》- 17.支持实时数据库,高并发保存测点数据。附:3.4 发布与版本更新说明。

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  7. java之泛型解说

    1.集合中只能装入引用数据类型,不能装入基本数据类型.如,装入int类型的数值123会自动装箱. 2.开发人员装入集合的数据类型不确定,所以它被设计成可以装入所有的Object. 3.新的问题产生,装 ...

  8. 20155215 2016-2017-2 《Java程序设计》第5周学习总结

    学号 2006-2007-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 尝试捕捉错误对象,try,catch. 如何抛出错误对象,throw语法. error代表系统错 ...

  9. JDK动态代理实现机制

    =========================================== 原文链接: JDK动态代理实现机制   转载请注明出处! =========================== ...

  10. PHP获得文件创建、修改、访问时间 filectime() filemtime() fileatime()

    转载博客 零度_PHP的博客   http://blog.sina.com.cn/s/blog_8edc37a801016hk1.html PHP获得文件创建.修改.访问时间 PHP filectim ...