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

資訊專欄INFORMATION COLUMN

造輪子系列(二): 史上最簡(jiǎn)單的長(zhǎng)連接通信協(xié)議及實(shí)現(xiàn)

Alliot / 2042人閱讀

摘要:背景現(xiàn)在寫(xiě)客戶端或者網(wǎng)頁(yè)的時(shí)候越來(lái)越多的需要與長(zhǎng)連接打交道尤其是在這個(gè)老板動(dòng)不動(dòng)就要搞一個(gè)聊天系統(tǒng)的時(shí)代后端大哥們于是分分鐘就能造一個(gè)基于或者的消息協(xié)議出來(lái)但是問(wèn)題在于每做一個(gè)新項(xiàng)目后端大哥們就能造出一個(gè)新協(xié)議而且能有各種神奇的限制比如說(shuō)要

背景

現(xiàn)在寫(xiě)客戶端或者網(wǎng)頁(yè)的時(shí)候, 越來(lái)越多的需要與長(zhǎng)連接打交道, 尤其是在這個(gè)老板動(dòng)不動(dòng)就要搞一個(gè)聊天系統(tǒng)的時(shí)代, 后端大哥們于是分分鐘就能造一個(gè)基于TCP或者WebSockets的消息協(xié)議出來(lái). 但是問(wèn)題在于每做一個(gè)新項(xiàng)目, 后端大哥們就能造出一個(gè)新協(xié)議, 而且能有各種神奇的限制. 比如說(shuō)要在長(zhǎng)連接當(dāng)中保持一個(gè)狀態(tài)機(jī), 發(fā)送某條消息后收到的下一條消息一定是XXX, 或者完全一個(gè)JSON就直接丟了出來(lái)等等. 雖然都能用, 但是卻需要在各種地方維護(hù)著不同的底層通信庫(kù), 沒(méi)有章法可依, 所以草擬了這個(gè)協(xié)議.

目前最熱門的消息協(xié)議莫過(guò)于MQTT和gRPC了, 前者被定義為A lightweight messaging protocol for small sensors and mobile devices, optimized for high-latency or unreliable networks, 即一個(gè)為傳感器和移動(dòng)設(shè)備定制的消息協(xié)議. 最大的特點(diǎn)莫過(guò)于其固定消息頭只有2字節(jié), 以及QoS服務(wù)質(zhì)量控制了. 對(duì)于前者, 無(wú)可厚非, 任何一個(gè)長(zhǎng)連接的消息協(xié)議都應(yīng)該可以做到如此, 甚至更簡(jiǎn)單(STMP便是如此), 其次其QoS設(shè)計(jì)使得通信層面就變得很復(fù)雜, 使得其更像一個(gè)消息隊(duì)列協(xié)議, 而不是簡(jiǎn)單的通信協(xié)議. 而gRPC則是一個(gè)基于ProtocolBuffers發(fā)展起來(lái)的RPC協(xié)議以實(shí)現(xiàn). 集成度很高, 底層基于HTTP 2, 所以通用性很好, 如果是做大項(xiàng)目并且團(tuán)隊(duì)有一定的技術(shù)/運(yùn)維積累的話, 是非常推薦的選擇, 但是這和STMP不沖突, STMP面向的是對(duì)協(xié)議健壯性要求不高, 只需要一個(gè)能用的規(guī)范的企業(yè)/團(tuán)隊(duì)中, 你可以用在Web端, 也可以用在客戶端, 或者智能家居等嵌入式設(shè)備中, 反觀gRPC, 則顯得過(guò)于龐雜.

簡(jiǎn)介

協(xié)議取名STMP, 意思是最簡(jiǎn)單的消息協(xié)議(The simplest message protocol). 項(xiàng)目托管在GitHub上, 包含了完整的協(xié)議文檔以及相關(guān)實(shí)現(xiàn), 詳細(xì)了解請(qǐng)移步GitHub, 同時(shí)歡迎提交PR/Issue, 地址是https://github.com/acrazing/stmp.

簡(jiǎn)單來(lái)說(shuō), STMP有以下特點(diǎn):

非常精簡(jiǎn)的固定頭部, 僅有一字節(jié)(二進(jìn)制序列化)

支持二進(jìn)制序列化(TCP)以及文本序列化(WebSockets), 文本序列化支持消息分包傳送(傳遞二進(jìn)制數(shù)據(jù))

與IP協(xié)議掩碼類似的上層路由控制

負(fù)載編碼格式對(duì)協(xié)議透明

心跳檢測(cè)

四種消息類型: 心跳, 請(qǐng)求, 通知, 回復(fù)

與HTTP協(xié)議類似的返回狀態(tài)碼控制

消息字段定義

一個(gè)全雙工的通信系統(tǒng)中, 雙端需要有效識(shí)別對(duì)方發(fā)來(lái)的消息, 并作出相應(yīng)的處理, 選擇是否回應(yīng)等操作, 所以除了實(shí)際的負(fù)載之外, 還需要若干標(biāo)志字段. STMP中, 完整的消息字段列表如下, 需要注意的是并不是每條消息都會(huì)包含所有的這些字段, 需要根據(jù)網(wǎng)絡(luò)環(huán)境以及消息類型確定應(yīng)該包含的字段列表. 但是如果某條消息包含了以下這些字段中的某一些字段的話,排序順序一定與字段在下面出現(xiàn)的順序相同.

消息類型(KIND): 表示一條消息的類型, 可能的取值有:

0: 心跳消息(Ping Message)

1: 請(qǐng)求消息(Request Message)

2: 通知消息(Notify Message)

3: 回復(fù)消息(Response Message)

消息編碼格式(ENCODING): 表示負(fù)載的編碼格式, 上層應(yīng)用/編解碼層收到消息后, 可以通過(guò)此字段對(duì)負(fù)載進(jìn)行解碼操作, 由于頭部長(zhǎng)度限制, 可能的取值范圍為0-7, 已經(jīng)約定的編碼格式如下:

0: 保留格式, 表示不包含負(fù)載, 此時(shí)消息中一定不存在PS以及PAYLOAD字段

1: Protocol Buffers, 參考 Protocol Buffers

2: JSON, 參考 JSON

3: MessagePack, 參考 MessagePack

4: BSON, 參考 BSON

5: 原始二進(jìn)制數(shù)據(jù)

消息ID(ID): 消息的臨時(shí)ID, 取值范圍為0x0000-0xFFFF, 用于請(qǐng)求與回復(fù)消息當(dāng)中, 請(qǐng)求方應(yīng)該保證在超時(shí)的時(shí)限內(nèi)此ID唯一, 回復(fù)方在回復(fù)時(shí)帶上此ID以供發(fā)送方識(shí)別

消息請(qǐng)求動(dòng)作(ACTION): 請(qǐng)求的動(dòng)作, 用于上層應(yīng)用進(jìn)行路由控制, 取值范圍為0x00000000-0xFFFFFFFF, 即32位整型, 上層應(yīng)用中可以寫(xiě)成xxx.xxx.xxx.xxx的形式, 與IP類似. 接收方在收到相應(yīng)的動(dòng)作后必需能夠正確識(shí)別, 并轉(zhuǎn)交給相應(yīng)的處理器進(jìn)行處理. 其中0x00-0xFF為保留動(dòng)作, 用于協(xié)議內(nèi)部使用. 目前已使用的動(dòng)作有:

0x00: 版本協(xié)商(Check Versions)

狀態(tài)碼(STATUS): 處理結(jié)果狀態(tài)碼, 用在回復(fù)消息中, 表明對(duì)請(qǐng)求的處理結(jié)果, 取值范圍為0x00-0xFF, 其中0x00-0x7F為保留取值, 含義與ACTION無(wú)關(guān), 0x80-0xFF為用戶定義的狀態(tài)值, 含義根據(jù)ACTION不同有可能不同. 目前已定義的狀態(tài)碼有(和HTTP類似, 只不過(guò)換了個(gè)值而已):

0x00: Ok, 200

0x10: MovedPermanently, 301

0x11: Found, 302

0x12: NotModified, 304

0x20: BadRequest, 400

0x21: Unauthorized, 401

0x22: PaymentRequired, 402

0x23: Forbidden, 403

0x24: NotFound, 404

0x25: RequestTimeout, 408

0x26: RequestEntityTooLarge, 413

0x27: TooManyRequests, 429

0x30: InternalServerError, 500

0x31: NotImplemented, 501

0x32: BadGateway, 502

0x33: ServiceUnavailable, 503

0x34: GatewayTimeout, 504

0x35: VersionNotSupported, 505

負(fù)載長(zhǎng)度(PS): 表示PAYLOAD的長(zhǎng)度, 以字節(jié)為單位, 取值范圍為0x00000000-0xFFFFFFFF, 即負(fù)載最大長(zhǎng)度為4Gb, 此字段存在與否由網(wǎng)絡(luò)環(huán)境與ENCODING決定, 如果ENCODING0, 或者網(wǎng)絡(luò)環(huán)境能夠正確的分包(比如WebSockets環(huán)境), 則一定不存在此字段, 否則一定存在此字段.

負(fù)載(PAYLOAD): 實(shí)際的負(fù)載, 長(zhǎng)度由PS或者網(wǎng)絡(luò)分包結(jié)果確定, 編碼方式由ENCODING決定, 協(xié)議本身不負(fù)責(zé)負(fù)載的編解碼, 需要交由上層的應(yīng)用進(jìn)行解釋.

消息類型

如前所述, STMP中消息分類四種類型, 不同的消息類型可能包含的字段及含義有所不同, 詳細(xì)如下:

心跳消息

雙端為了保證對(duì)方連接有效性, 必需定期發(fā)送一個(gè)心跳消息給對(duì)方, 此消息一定不包含任何除了KIND外的其它任何字段. 同時(shí)此消息不需要 回復(fù), 如果一方在約定的時(shí)間內(nèi)沒(méi)有收到對(duì)方發(fā)送的心跳消息, 則表明對(duì)方已經(jīng)斷開(kāi)連接或者出現(xiàn)異常, 應(yīng)該立即斷開(kāi)連接.

請(qǐng)求消息

此消息表示發(fā)送方請(qǐng)求接收方返回某一個(gè)資源, 如果在指定的時(shí)間內(nèi)未收到接收方的回復(fù), 則放棄等待, 并向上層應(yīng)用返回一個(gè)STATUS0x25的回復(fù), 表示請(qǐng)求超時(shí).
此消息一定包含KIND, ENCODING, ID, ACTION字段, 可能包含PS, PAYLOAD字段, 一定不包含STATUS字段.

通知消息

此消息表示發(fā)送方向接收方發(fā)送一個(gè)通知, 接收方無(wú)需回復(fù)此消息.

此消息一定包含KIND, ENCODING, ACTION字段, 可能包含PS, PAYLOAD字段, 一定不包含ID, STATUS字段.

回復(fù)消息

此消息表示發(fā)送方向接收方發(fā)送一個(gè)回復(fù)消息以回復(fù)對(duì)方曾經(jīng)發(fā)送的某一條請(qǐng)求消息, 此消息的ID為接收方發(fā)送的此條請(qǐng)求消息ID. 如果上層應(yīng)用在指定的時(shí)間內(nèi)未返回消息, 則向發(fā)送方發(fā)送一個(gè)STATUS0x34的回復(fù)消息, 表明上層應(yīng)用處理超時(shí).

此消息一定包含KIND, ENCODING, ID, STATUS字段, 可能包含PS, PAYLOAD字段, 一定不包含ACTION字段.

消息序列化

針對(duì)不同的網(wǎng)絡(luò)環(huán)境, 協(xié)議制定了兩套不同的序列化方式以應(yīng)對(duì), 主要原因是瀏覽器環(huán)境中將字符串轉(zhuǎn)換成ArrayBuffer再通過(guò)WebSockets發(fā)送性能實(shí)在無(wú)法直視(實(shí)現(xiàn)方式可以參考stmp/impl/js/stmp/text.ts, 主要是將UTF-16編碼和字符串轉(zhuǎn)換成UTF-8的Uint8Array), 同時(shí)為了更好的Web端調(diào)試, 所以制定了一套文本序列化方案.

二進(jìn)制序列化

二進(jìn)制序列化中, 固定頭部占一個(gè)字節(jié), 包含KIND以及ENCODING字段, 如果KIND0, 則ENOCDING也必需為0, 表示一個(gè)心跳消息. 完整的結(jié)構(gòu)如下:

|   0 ... 7   |  8 ... 15  |  16 ... 23  |  24 ... 31  |
| FixedHeader |           ID             |    ACTION   |
|               ACTION                   |    STATUS   |
|                         PS                           |
|                 PAYLOAD    ...                       |

其中的多字節(jié)字段, 包括ID, ACTION, PS字段, 如果存在的話, 一定BigEndian的方式傳遞. 此外, 固定頭部如下:

|   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7   |
|     KIND      |       ENCODING        |   0   |   0   |   0   |

最后三個(gè)位為保留位(未用到), 全部置零.

文本就序列化

所有的字段通過(guò)字符|連接, 即:

KIND(1)|ENCODING(1)|ID?(1-5)|ACTION?(1-10)|STATUS?(1-3)|PS?(1-10)|PAYLOAD?(...)

消息分割, 在使用文本序列化方式傳遞二進(jìn)制數(shù)據(jù)時(shí), 瀏覽器環(huán)境不能高效的將二者混雜在一起, 所以允許分成兩個(gè)包進(jìn)行傳送, 前者傳遞頭部信息, 后者傳遞實(shí)際的二進(jìn)制PAYLOAD, 此時(shí)ENCODING一定不0, 同時(shí), PAYLOAD在頭部包中不存在. WebSockets自身保證了包的有序性.

對(duì)于一個(gè)心跳消息, 只有一個(gè)KIND字段, 所以其結(jié)果一定為"0".

區(qū)分文本消息與二進(jìn)制消息

這是比較有趣的地方, 文本消息和二進(jìn)制消息可以通過(guò)首字節(jié)完全區(qū)別開(kāi)來(lái): 對(duì)于文本消息, 首字節(jié)為"0", "1", "2", "3"中的一個(gè), 即0x30-0x33, 而對(duì)于二進(jìn)制消息, 要么為0x00(心跳消息), 要么大于或者等于0x40, 因?yàn)?b>KIND不為0時(shí)其值一定大于0b01000000.

版本協(xié)商

協(xié)議版本有兩個(gè)字段, 分別為MAJORMINOR, 二者取值范圍均為015, 即0x00xF, 可以序列化為MAJOR.MINOR的形式.

當(dāng)前協(xié)議版本為0.1.

客戶端在發(fā)起連接成功后, 需要發(fā)送一個(gè)ACTION為0x00的消息給服務(wù)端, 消息ID必需為0, 負(fù)載編碼方式為Raw, 負(fù)載為客戶端可接受的版本號(hào)
列表. 服務(wù)端在收到此消息后, 如果可以處理客戶端發(fā)送過(guò)來(lái)的版本列表中的某一個(gè), 則回復(fù)一個(gè)STATUS為Ok的回復(fù)消息, 負(fù)載為所選擇的協(xié)議版本
號(hào), 如果不能處理, 則返回一個(gè)VersionNotSupported錯(cuò)誤消息, 負(fù)載為空, 并且關(guān)閉連接.

版本號(hào)序列化

在二進(jìn)制消息中, 一個(gè)版本號(hào)序列化為1字節(jié)長(zhǎng)度的信息, 其中前4位為MAJOR, 后4位為MINOR值. 多個(gè)版本號(hào)直接連接在一起. 在文本消息中, 一個(gè)版本號(hào)序列化為2字節(jié)長(zhǎng)度的信息, 其中前1字節(jié)為MAJOR, 后1字節(jié)為MINOR值, 多個(gè)版本號(hào)直接相連.

實(shí)現(xiàn)

目前僅實(shí)現(xiàn)了Golang和JS的簡(jiǎn)單的消息編解碼部分, 地址在: go版本, js版本, 還有很多工作要做T_T, 如果有人提PR就好了?????.

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/84446.html

相關(guān)文章

  • Android OkHttp 上最優(yōu)雅的設(shè)置baseUrl

    前言 RxHttp截止本文發(fā)表已經(jīng)推廣了4個(gè)禮拜,目前已經(jīng)有了141個(gè)star,如下: showImg(https://user-gold-cdn.xitu.io/2019/5/20/16ad5f3b6d10d9be); 其中一文,Android 史上最優(yōu)雅的實(shí)現(xiàn)文件上傳、下載及進(jìn)度的監(jiān)聽(tīng)更是得到了大神劉皇叔微信公眾號(hào)的推送,歡迎讀者關(guān)注劉皇叔微信公眾號(hào)「劉望舒」,每天都有精彩的文章推送,真的很棒...

    番茄西紅柿 評(píng)論0 收藏0
  • 架構(gòu)~微服務(wù)

    摘要:接下來(lái)繼續(xù)介紹三種架構(gòu)模式,分別是查詢分離模式微服務(wù)模式多級(jí)緩存模式。分布式應(yīng)用程序可以基于實(shí)現(xiàn)諸如數(shù)據(jù)發(fā)布訂閱負(fù)載均衡命名服務(wù)分布式協(xié)調(diào)通知集群管理選舉分布式鎖和分布式隊(duì)列等功能。 SpringCloud 分布式配置 SpringCloud 分布式配置 史上最簡(jiǎn)單的 SpringCloud 教程 | 第九篇: 服務(wù)鏈路追蹤 (Spring Cloud Sleuth) 史上最簡(jiǎn)單的 S...

    xinhaip 評(píng)論0 收藏0
  • 【大量干貨】上最完整的Tengine HTTPS原理解析、實(shí)踐與調(diào)試

    摘要:內(nèi)容主要有四個(gè)方面趨勢(shì)基礎(chǔ)實(shí)踐調(diào)試。一趨勢(shì)這一章節(jié)主要介紹近幾年和未來(lái)的趨勢(shì),包括兩大瀏覽器和對(duì)的態(tài)度,以及淘寶天貓和阿里云的實(shí)踐情況。完整性是指為了避免網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)被非法篡改,使用算法來(lái)保證消息的完整性。 摘要: 本文邀請(qǐng)阿里云CDN HTTPS技術(shù)專家金九,分享Tengine的一些HTTPS實(shí)踐經(jīng)驗(yàn)。內(nèi)容主要有四個(gè)方面:HTTPS趨勢(shì)、HTTPS基礎(chǔ)、HTTPS實(shí)踐、HTTPS...

    snowell 評(píng)論0 收藏0
  • 即時(shí)通信相關(guān)技術(shù)總結(jié)

    摘要:解決問(wèn)題即時(shí)通信要解決三方面的問(wèn)題雙全工通信低延時(shí)支持跨域各種即時(shí)通信技術(shù)輪詢客戶端定時(shí)向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器接到請(qǐng)求后馬上返回響應(yīng)信息并關(guān)閉連接。優(yōu)點(diǎn)實(shí)現(xiàn)真正的即時(shí)通信,而不是偽即時(shí)。 解決問(wèn)題 即時(shí)通信要解決三方面的問(wèn)題: 雙全工通信 低延時(shí) 支持跨域 各種即時(shí)通信技術(shù) 輪詢 客戶端定時(shí)向服務(wù)器發(fā)送Ajax請(qǐng)求,服務(wù)器接到請(qǐng)求后馬上返回響應(yīng)信息并關(guān)閉連接。優(yōu)點(diǎn):后端程序編寫(xiě)比...

    reclay 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<