• 前端小工具:protobufjs数据传输


    前端使用protobufjs,数据传输protobufjs使用记录

    protobuf.js

    协议缓冲区是一种与语言无关的、与平台无关的、可扩展的序列化结构化数据的方法,用于通信协议、数据存储等,最初由Google设计(请参阅)。

    协议.js是一个纯JavaScript实现,支持节点.js和浏览器。它易于使用,速度极快,并且可以与.proto文件一起开箱即用

    1, 安装protobufjs

    npm install protobufjs [--save --save-prefix=~]

    2.使用

    // const protobufjs = require('protobufjs')
    import protobufjs from 'protobufjs'


    // 要用到load模块
      const { load } = protobufjs

    实例:

    export default class protobuf {
        static exportBuffer(parsedJsonList, molecule, proto , taskitem){
            return new Promise((resolve, reject) => {
                load(proto, (err, root) => {
                  if (err) {
                    console.log(err)
                    return reject(new Error('proto文件加载出错!'));
                  }
                  let prototxts = []
                  parsedJsonList.forEach(parsedJson => {
                    let parsedMessage = root.lookupType('TIV.' + parsedJson.header.type + 'Def')
                    const single = parsedMessage.create(parsedJson)
                    const singleBuffer = parsedMessage.encode(single).finish() // 这个singleBuffer发给后台就好
                    prototxts.push({
                      msgId: parsedJson.id,
                      msgType: parsedJson.header.type,
                      msgContent: singleBuffer,
                      taskType: parsedJson.taskType,
                      isEntry: isEntry(parsedJson.header.type, parsedJson.id, molecule)
                    })
                  })
          
                  let prototxtsMessage = root.lookupType('TIV.AllOperatorPb')
                  const all = prototxtsMessage.create({
                    allOperatorPb: prototxts,
                    taskFlow: taskitem ? taskitem : ''
                  })
                  const allBuffer = prototxtsMessage.encode(all).finish() // 这个buffer发给后台就好
                  const b64 = btoa(String.fromCharCode.apply(null, allBuffer))
                //   this.analysisBuffer(b64, proto)
                  resolve(b64);
                })
            })
        }
        static analysisBuffer(b64, proto) {
            let allBuffer = atob(b64).split('').map(function (c) { return c.charCodeAt(0) })
            return new Promise((resolve, reject) => {
                load(proto, (err, root) => {
                    if (err) {
                        reject(err)
                        return console.log('proto文件加载出错');
                    }
                    let prototxtsMessage = root.lookupType('TIV.AllOperatorPb')
                    const alldata = prototxtsMessage.decode(allBuffer)
                    alldata.allOperatorPb.map(item => {
                        let parsMessage = root.lookupType('TIV.' + item.msgType + 'Def')
                        const fields = [];
                        if (Object.keys(parsMessage.Parameter.fields).length > 0) {
                            Object.keys(parsMessage.Parameter.fields).forEach(ikey => {
                                let value = 0;
                                if (parsMessage.Parameter.fields[ikey].type === "bool") {
                                    value = false;
                                }
                                fields.push({
                                    title: ikey,
                                    value: parsMessage.Parameter.fields[ikey].typeDefault || value
                                })
                            })
                        }
                        const prototxt = parsMessage.decode(item.msgContent)
                        fields.forEach(field => {
                            if(prototxt['param']){
                                prototxt['param'][field.title] = prototxt['param'][field.title] ? prototxt['param'][field.title] : field.value;
                            }  
                        })
                        prototxt.header.type = prototxt.header.type.split('Operator')[0]
                        item.msgContent = formatInit(prototxt)
                    })
                    if(process.env.NODE_ENV === 'development'){
                        console.log('解析后json数据:',alldata.allOperatorPb)
                    }
                    resolve(alldata.allOperatorPb);
                })
            })
        }
    }
    protobufjs使用,数据的转换依赖 proto配置文件,protobufjs默认支持本地同源文件请求,如果proto文件是固定的不需要更改的,配置在前端静态文件就好了;如何会动态变更的话,需要用到绝对路径,需要解决跨域问题;

    修改protobufjs对象原型默认的load请求文件方式:

    protobufjs.util.fetch.xhr = function fetch_xhr(filename, options, callback) {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange /* works everywhere */ = function fetchOnReadyStateChange() {
    
            if (xhr.readyState !== 4)
                return undefined;
    
            // local cors security errors return status 0 / empty string, too. afaik this cannot be
            // reliably distinguished from an actually empty file for security reasons. feel free
            // to send a pull request if you are aware of a solution.
            if (xhr.status !== 0 && xhr.status !== 200)
                return callback(Error("status " + xhr.status));
    
            // if binary data is expected, make sure that some sort of array is returned, even if
            // ArrayBuffers are not supported. the binary string fallback, however, is unsafe.
            if (options.binary) {
                var buffer = xhr.response;
                if (!buffer) {
                    buffer = [];
                    for (var i = 0; i < xhr.responseText.length; ++i)
                        buffer.push(xhr.responseText.charCodeAt(i) & 255);
                }
                return callback(null, typeof Uint8Array !== "undefined" ? new Uint8Array(buffer) : buffer);
            }
            return callback(null, xhr.responseText);
        };
    
        if (options.binary) {
            // ref: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Receiving_binary_data_in_older_browsers
            if ("overrideMimeType" in xhr)
                xhr.overrideMimeType("text/plain; charset=x-user-defined");
            xhr.responseType = "arraybuffer";
        }
    
        xhr.open("GET", filename);
        let headers = options.headers || {};
    
        if (process.env.NODE_ENV !== 'development') {
            headers['X-TC-Action'] = 'WorkbenchPb'
            headers['X-TC-Region'] = 'ap-guangzhou'
            headers['X-TC-Timestamp'] = Math.round(new Date().getTime()/1000).toString()
            headers['X-TC-Service'] = 'AMTPGate'
            headers['X-TC-Version'] = '2020-05-14'
        }
    
        for (let item in headers) {
            if (headers.hasOwnProperty(item) && headers[item] !== null) {
                xhr.setRequestHeader(item, headers[item]);
            }
        }
        xhr.send();
    };
    Buffer数据流,传输速度非常快,数据保密性更强,前后端数据传输跟健壮。
    文中的示例,最终使用的是base64,这样对ajax请求无影响,直接使用post请求,即可。如果直接用buffer,需要自己封装ajax;
    大概设置:
    xhr.responseType = 'blob'
    protobuf.js库很强大,可以继续研究一下。

    同时使用protobuf.js,和后端使用规范版本要一致。

    没有终点,没有彼岸,坚持就好,愿岁月如初

    smallbore,world
  • 相关阅读:
    学习python第二天
    学习python第一天
    SQL操作
    JAR规范 JAR File Specification
    IDEA快捷键
    Fibonacci数列
    AnyHandler
    测试UDP
    Eclipse卡顿设置
    服务器初始化操作
  • 原文地址:https://www.cnblogs.com/bore/p/14341754.html
Copyright © 2020-2023  润新知