成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為了一份Mock數據,開啟了Protobuf的救贖之路

存儲 存儲軟件
Protobuf 作為一種跨平臺、語言無關、可擴展的序列化結構數據的方法,已廣泛應用于網絡數據交換及存儲。

[[421682]]

一、背景

近期在做一個需求,該需求需要和后端進行交互,為了并行開發,就跟后端產生了如下的對話:

前端:老鐵,可以給份mock數據嗎?

后端:mock數據太麻煩了,你自己來吧!!!

前端:我怎么知道數據長啥樣,如何mock呀!(可憐)

后端:按照約定的接口mock就行,直接給我拋出了一個proto文件

前端:此時已經一臉懵逼狀態,proto是個啥?如何根據proto來mock一份數據?后端為什么要用proto,JSON不香嗎?為了彌補上自己欠缺的一環,開啟了Protobuf的救贖之路。

二、Protobuf是什么?

Protobuf 作為一種跨平臺、語言無關、可擴展的序列化結構數據的方法,已廣泛應用于網絡數據交換及存儲。其目前已經支持的開發語言有多種(C++、Java、Python、Objective-C、C#、JavaNano、JavaScript、Ruby、Go、PHP),詳情可參考(https://github.com/52im/protobuf)。其具有如下優缺點:

優點

(1)序列化后體積小,適合網絡傳輸

(2)支持跨平臺、多語言

(3)具有較好的升級和兼容性(具有向后兼容的特性,更新數據結構以后,老版本依舊可以兼容)

(4)序列化和反序列化的速度較快

缺點

Protobuf是二進制協議,編碼后的數據可讀性差

三、Protobuf的結構

Protobuf用法的使用有很多,本次就通過一個例子來看看其基本使用,具體使用可以在網上搜索相關文檔進行學習。

  1. syntax = "proto2" 
  2. package transferData; 
  3.  
  4. message transferMessage { 
  5.     required string name = 1; 
  6.     required int32 age = 2; 
  7.     enum SexEnum { 
  8.         Boy = 0; 
  9.         Girl = 1; 
  10.     } 
  11.     optional SexEnum SexEnum = 3; 

1.syntax = "proto2";

該行用于指定語法版本,目前有兩個版本proto2和proto3,兩個版本不兼容,如果不指定,默認語法是proto2.

2.package transferData;

用于定義該包的包名;

3.message

message是Protobuf中最基本的數據單元,其中可以嵌套message或其它的基礎數據類型的成員;

4.屬性

message中的每一行就是一個屬性,例如required string name = 1,其組成如下所示:

標注 類型 屬性名 屬性順序號 [options]
required string name = 1 一些可選項

(1)標注有三種:

required:必選屬性;

optional:可選屬性;

repeated:重復字段,類似于動態數組;

(2)類型有多種,每種語言不同,例如:int32、int64、int、float、double、string等;

(3)屬性名:用于表征該屬性的名稱;

(4)屬性順序號:protobuf為了提高數據的壓縮和可選性等功能定義的,需要按照順序進行定義,且不允許有重復;

(5)[options]:protobuf提供了一些內置的options可供選擇想,可大大提高protobuf的擴展性。

5.enum

定義消息類型時,可能需要某字段值是一些預設值之一,此時枚舉類型就能夠發揮作用了。

注:protobuf還有很多用法,此處只做了簡單介紹,有喜歡的同學可進一步自己深入學習。

四、實戰

聊了那么多,下面就進入實戰環節,實戰將在node運行環境下,構建TCP連接,然后由客戶端發送經過Protobuf序列化的內容至服務端,然后服務端接收到信息之后進行解析,其中proto文件的序列化和反序列化將使用protobuf.js包,其是一個純 JavaScript 實現,支持node.js和瀏覽器。它易于使用,速度極快,并且可以使用.proto文件開箱即用!(https://www.npmjs.com/package/protobufjs)

4.1 基本使用

本次解析.proto文件使用的是protobuf.js包,常用的方法主要有以下幾個:

1.load()

用該函數加載對應的.proto文件,加載完成之后才能夠使用里面的message以及進行后續的操作;

2.lookupType()

在加載完.proto后,需要對使用的message進行初始化,即完成message實例化的過程;

3.verify()

該函數用于驗證普通對象是某滿足對應的message結構;

4.encode()

編碼一個message實例或者可利用的普通js對象;

5.decode()

解碼buffer至一個message實例,解碼失敗會排除錯誤;

6.create()

從一系列屬性創建一個新的message實例,其優于通過fromObject創建,是由于其不會產生冗余的轉換;

7.fromObject()

將任何無效的普通js對象轉換為message實例;

8.toObject()

轉換一個message實例去一個任意的普通js對象。

該庫的使用還有一些其它方法,可以通過看其對應文檔進行學習。對于上述轉換關系如下圖所示(來自于官方文檔):

4.2 服務端

其是服務端,當接收到客戶端發送的消息后,利用protobufjs庫中的decode函數進行解析,獲取解析后的結果。

  1. const net = require('net'); 
  2. const protobuf = require('protobufjs'); 
  3.  
  4. const decodeData = data => { 
  5.     protobuf.load('./transfer.proto'
  6.     .then(root => { 
  7.         const transferMessage = root.lookupType('transferData.transferMessage'); 
  8.  
  9.         const result = transferMessage.decode(data); 
  10.         console.log(result); // transferMessage { name'狍狍', age: 1, sexEnum: 1 } 
  11.     }) 
  12.     .catch(console.log); 
  13. const server = net.createServer(socket => { 
  14.     socket.on('data', data =>{ 
  15.         decodeData(data); 
  16.     }); 
  17.  
  18.     socket.on('close', () => { 
  19.         console.log('client disconnected!!!'); 
  20.     }); 
  21. }); 
  22.  
  23. server.on('error', err => { 
  24.     throw new Error(err); 
  25. }); 
  26.  
  27. server.listen(8081, () => { 
  28.     console.log('server port is 8081'); 
  29. }); 

4.3 客戶端

其是客戶端對應的代碼,利用protobufjs庫進行相應的操作,將序列化后的內容發送至服務端。

  1. const net = require('net'); 
  2. const protobuf = require('protobufjs'); 
  3.  
  4. const data = { 
  5.     name'狍狍'
  6.     age: 1, 
  7.     sexEnum: 1 
  8. }; 
  9.  
  10. let client = new net.Socket(); 
  11. client.connect({ 
  12.     port: 8081 
  13. }); 
  14.  
  15. client.on('connect', () => { 
  16.     setMessage(data); 
  17. }); 
  18.  
  19. client.on('data', data => { 
  20.     console.log(data); 
  21.     client.end(); 
  22. }); 
  23.  
  24. function setMessage(data) { 
  25.     protobuf.load('./transfer.proto'
  26.     .then(root =>{ 
  27.         // 根據proto文件中的內容對message進行實例化 
  28.         const transferMessage = root.lookupType('transferData.transferMessage'); 
  29.  
  30.         // 驗證 
  31.         const errMsg = transferMessage.verify(data); 
  32.         console.log('errMsg', errMsg); 
  33.         if (errMsg) { 
  34.             throw new Error(errMsg); 
  35.         } 
  36.  
  37.         // 轉換為message實例 
  38.         const messageFromObj = transferMessage.fromObject(data); 
  39.         console.log('messageFromObj', messageFromObj); 
  40.  
  41.         // 編碼 
  42.         const buffer = transferMessage.encode(messageFromObj).finish(); 
  43.         console.log(buffer); 
  44.  
  45.         // 發送 
  46.         client.write(buffer); 
  47.     }) 
  48.     .catch(console.log); 

 

責任編輯:武曉燕 來源: 前端點線面
相關推薦

2019-04-16 13:57:59

戴爾

2019-11-14 21:21:50

數據挖掘數據處理數據分析

2018-01-29 16:29:35

數據開發從業

2020-07-15 15:38:15

人臉識別照片活化手機

2018-08-15 13:49:06

數據分析學習Python

2025-07-03 09:28:44

架構群消息開發

2019-03-24 14:14:40

代碼閱讀源代碼

2020-10-11 21:52:10

數據AI指南

2018-07-29 15:33:04

2019-12-03 10:28:53

編程語言PythonJava

2015-03-19 15:17:11

2023-09-29 22:41:26

Kubernetes云原生

2024-11-07 08:50:56

用戶分析分類維度標簽

2018-05-03 07:06:21

開發規范iOS

2023-09-01 14:02:25

用戶分析攻略

2020-07-24 09:44:03

安全駐場工程師網絡安全IT安全

2018-03-09 10:28:30

生態報告簽收

2022-04-29 08:48:25

開源

2019-07-17 07:07:54

MySQL數據庫索引

2024-07-10 12:11:30

數據經營分析業務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品久久久久久久久久久 | 日韩成人免费视频 | 中文字幕 欧美 日韩 | 久久国产精品网站 | 国产精品国产成人国产三级 | 久久成人久久 | 91高清免费观看 | 三级黄视频在线观看 | 一级毛片色一级 | 成人免费在线观看 | 欧美精品综合 | 亚洲福利在线观看 | 欧美激情欧美激情在线五月 | 好姑娘影视在线观看高清 | 日韩精品成人 | 激情五月综合网 | www97影院 | 成人毛片视频免费 | 国产精品色 | 国产一区二区三区在线看 | 毛片一级片 | 国产精品久久久久久二区 | 成av在线 | 国产精品高清在线 | 91精品国产综合久久久久蜜臀 | 国产成人综合亚洲欧美94在线 | 黄色一级电影免费观看 | 成人网在线观看 | 三级黄片毛片 | 天堂色综合 | 在线观看av不卡 | 国产精品一区二区av | 国产美女在线精品免费 | 精品久草 | 国产精品一区二区三 | 国产精品99久久久久 | 国产精品极品美女在线观看免费 | 九九久久国产精品 | 成人在线不卡 | 亚洲欧美v| 国产精品一二三区 |