亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

基于 protobuf 協(xié)議實現(xiàn)高性能的 IM 客戶端

ssshooter / 2895人閱讀

摘要:涉及到計算機基礎知識,例如字節(jié)緩沖大小端等。是指用多少位表示的整數(shù),例如就是用位即一個字節(jié)表示的整數(shù),二進制范圍是,對應的十進制就是。開發(fā)時通訊雙方或者多方終端都遵循協(xié)議。

這里記錄了使用 protobuf 協(xié)議與服務端數(shù)據(jù)交互的相關內容和知識。

涉及到計算機基礎知識,例如字節(jié)、buffer 緩沖、大小端等。

字節(jié) / Byte

1 字節(jié)代表了 8 位(bit)二進制,1 位就是 0 或 1,也是計算機最小單位。

Uint 與 Int

Int 是帶正負號的整數(shù),Uint 是從 0 開始計的整數(shù)。

Uintx 是指用多少表示的整數(shù),例如 Uint8 就是用 8位(即一個字節(jié)) 表示的整數(shù),二進制范圍是 00000000 ~ 11111111,對應的十進制就是 0 ~ 255。

但是人類的數(shù)學里面負數(shù),所以 Int8 就描述了包含負數(shù)在內的整數(shù)范圍,即十進制的 -128 ~ 127

更多描述如下所示

Uint8 -- (0 to 2^8 - 1)
Int8 -- (-2^7 to +2^7 - 1)

Uint16 -- (0 to 2^16 - 1)
Int16 -- (-2^15 to +2^15 - 1)

Uint32 -- (0 to 2^32 - 1)
Int32 -- (-2^31 to +2^31)

Uint64 -- (0 to 2^64 - 1)
Int64 -- (-2^63 to +2^63 - 1)
ArrayBuffer

ArrayBuffer?對象用來表示通用的、固定長度的原始二進制數(shù)據(jù)緩沖區(qū)。參考MDN

// 以下為創(chuàng)建 12 個字節(jié)的 buffer 的例子

const buffer = new ArrayBuffer(12);

上面的操作代表向操作系統(tǒng)申請了 12 字節(jié)的二進制緩沖,大概如下分布

| 00000000 | 00000000 | 00000000 | 00000000 | ...(還有8字節(jié))

ArrayBuffer 對象并不能直接被操作,需要通過 TypedArray 對象實例或者 DataView 實例作為橋梁來操作。

// Uint8Array 的單位為一字節(jié)與 ArrayBuffer 的基本單位吻合
const uint8 = new Uint8Array(buffer);

console.log(uint0) // 輸出 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

uint8[0] = 12; // 此時 buffer 變成 [12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

TypedArray 對象一覽 MDN

類型 大?。ㄗ止?jié)單位) 描述 Web IDL type
Int8Array 1 8位二進制帶符號整數(shù) -2^7~(2^7) - 1 byte
Uint8Array 1 8位無符號整數(shù) 0~(2^8) - 1 octet
Int16Array 2 16位二進制帶符號整數(shù) -2^15~(2^15)-1 short
Uint16Array 2 16位無符號整數(shù) 0~(2^16) - 1 unsigned short
Int32Array 4 32位二進制帶符號整數(shù) -2^31~(2^31)-1 long
Uint32Array 4 32位無符號整數(shù) 0~(2^32) - 1 unsigned int
Float32Array 4 32位IEEE浮點數(shù) unrestricted float
Float64Array 8 64位IEEE浮點數(shù) unrestricted double

除了 TypedArray,還可以通過 DataView 來做更細致的操作

例如我們需要在特定字節(jié)段內寫入對應的數(shù)據(jù)

| DataLen 4 個字節(jié) | SessionID 8 個字節(jié) | ...

const view = new DataView(buffer);

const DataLen = 100; // buffer 數(shù)據(jù)總長度
const SessionID = 123456789; // SessionID

// 最后的參數(shù)為大小端排序
view.setUint32(0, DataLen, true);
view.setBigUint64(4, BigInt(SessionID), true);

讀取內容

const view = new DataView(buffer);

// 讀取小端字符順序
const DataLen = view.getUint32(0, true);
const SessionID = view.getBigUint64(4, true);
什么是大小端

Little-Endian就是低位字節(jié)排放在內存的低地址端,高位字節(jié)排放在內存的高地址端。

Big-Endian就是高位字節(jié)排放在內存的低地址端,低位字節(jié)排放在內存的高地址端。

更多詳情參考維基百科的字節(jié)順序

JS 的大數(shù)處理

JS 并不能處理 Int64 精度的數(shù),所以在 stage 3 引入了 BigInt API,解決大數(shù)精度問題,ChromeFirefox 已經支持,但是 Safari 并不支持,需要用另外的辦法處理。

兼容方式參考 這里

Protobuf 應用

Google Protocol Buffers 是一種輕便高效的結構化數(shù)據(jù)存儲格式,可以用于結構化數(shù)據(jù)串行化,或者說序列化。

開發(fā)時通訊雙方或者多方終端都遵循 proto 協(xié)議。

然后看看前端如何使用 protobuf

Google 官方的庫對 JS 支持不是太友好,這里我們使用 protobuf.js 庫

創(chuàng)建一個 sdk.proto 文件

syntax = "proto3";

package yourPackage;

message LoginReq {
  string UserName = 1;
  string Password = 2;
}
yarn add protobufjs -D

# 使用 protobufjs 提供的 Command line
pbjs ./sdk.proto -t static-module > ./sdk.js

# 生成 ts 聲明文件
pbts -o ./sdk.d.ts ./sdk.js

生成好文件即可使用

import SDK from "./sdk";

const { LoginReq } = SDK.yourPackage;

const payload = {
  UserName: "alex",
  Password: "123"
}

const message = LoginReq.create(payload); // or use .fromObject if conversion is necessary

// encode 信息
const protoBuffer = LoginReq.encode(message).finish();

// 把 protobuf buffer 寫入到上面的 SessionID buffer 信息中

const uint8 = new Uint8Array(buffer);
uint8.set(protoBuffer, offset)

// 使用 websocket 發(fā)送 arrayBuffer 數(shù)據(jù)
const socket = new WebSocket(host)
socket.onopen = () => {
  socket.send(protoBuffer)
}
socket.onmessage = () => {
  // decode operator
}
總結

這里只是簡單的記錄過程,如果想要更多細節(jié)的信息,可以參考 little-chat 的源碼

參考

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/106373.html

相關文章

  • 帶入gRPC:gRPC及相關介紹

    摘要:原文地址帶入及相關介紹項目地址作為開篇章,將會介紹相關的一些知識。 原文地址:帶入gRPC:gRPC及相關介紹 項目地址:go-grpc-example 作為開篇章,將會介紹 gRPC 相關的一些知識。簡單來講 gRPC 是一個 基于 HTTP/2 協(xié)議設計的 RPC 框架,它采用了 Protobuf 作為 IDL 你是否有過疑惑,它們都是些什么?本文將會介紹一些常用的知識和概念,更詳...

    y1chuan 評論0 收藏0
  • 帶入gRPC:gRPC及相關介紹

    摘要:帶入及相關介紹原文地址帶入及相關介紹項目地址作為開篇章,將會介紹相關的一些知識。 帶入gRPC:gRPC及相關介紹 原文地址:帶入gRPC:gRPC及相關介紹 項目地址:go-grpc-example 作為開篇章,將會介紹 gRPC 相關的一些知識。簡單來講 gRPC 是一個 基于 HTTP/2 協(xié)議設計的 RPC 框架,它采用了 Protobuf 作為 IDL 你是否有過疑惑,它們都...

    AJie 評論0 收藏0
  • netty 基于 protobuf 協(xié)議 實現(xiàn) websocket 版本簡易客服系統(tǒng)

    摘要:結構作為服務端作為序列化數(shù)據(jù)的協(xié)議前端通訊演示地址服務端實現(xiàn)啟動類長連接示例主線程組從線程組請求的解碼和編碼把多個消息轉換為一個單一的或是,原因是解碼器會在每個消息中生成多個消息對象主要用于處理大數(shù)據(jù)流,比如一個大小的文件如果你直接傳輸肯定 結構 netty 作為服務端 protobuf 作為序列化數(shù)據(jù)的協(xié)議 websocket 前端通訊 演示 GitHub 地址 showImg(...

    wua_wua2012 評論0 收藏0
  • netty 基于 protobuf 協(xié)議 實現(xiàn) websocket 版本簡易客服系統(tǒng)

    摘要:結構作為服務端作為序列化數(shù)據(jù)的協(xié)議前端通訊演示地址服務端實現(xiàn)啟動類長連接示例主線程組從線程組請求的解碼和編碼把多個消息轉換為一個單一的或是,原因是解碼器會在每個消息中生成多個消息對象主要用于處理大數(shù)據(jù)流,比如一個大小的文件如果你直接傳輸肯定 結構 netty 作為服務端 protobuf 作為序列化數(shù)據(jù)的協(xié)議 websocket 前端通訊 演示 GitHub 地址 showImg(...

    Shihira 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<