博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
websoket使用Protocol Buffers3.0传输
阅读量:6374 次
发布时间:2019-06-23

本文共 3038 字,大约阅读时间需要 10 分钟。

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

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

定义一个.proto

syntax = "proto3";// Tokenmessage MyModel{    string UserID = 1;    string Device = 3;}message Message{    string ChannelID = 1;    bytes Content  = 4;}

加载:

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对象。另外一个是兼容性处理。的兼容性如下:

比如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的方式。

 

转载地址:http://trjqa.baihongyu.com/

你可能感兴趣的文章
内存数据管理(第2版)
查看>>
DiskSerial & CPUInfo
查看>>
svn里的branch、trunk、tag的用处
查看>>
一起谈.NET技术,Mono向Mac OS应用程序开发示好
查看>>
大型高性能ASP.NET“.NET研究”系统架构设计
查看>>
android搞的一个登录界面
查看>>
浅谈C# 匿名变量
查看>>
C++ Extensions: Reference examples
查看>>
geotools修改shapefile 属性名乱码问题 (转载)
查看>>
表变量与临时表的优缺点
查看>>
空类型指针和其他类型指针转换根本原则
查看>>
转:5 Ways To Fix Slow 802.11n Speed
查看>>
IntelliJ IDEA 11新特性介绍
查看>>
查看Oracle字符集
查看>>
CString的GetBuffer用法,GetBuffer本质,GetBuffer常见问题解决方法 .
查看>>
Facebook KeyHash生成方法
查看>>
zz 游戏程序员的学习之路(中文版)
查看>>
ASP.NET 安全系列 Membership三步曲之入门篇 - Jesse Liu
查看>>
Window 上安装Node.js
查看>>
CSRF攻击与防御(写得非常好)
查看>>