成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于 Netty 的可插拔業(yè)務(wù)通信協(xié)議的實現(xiàn)「1」協(xié)議描述及基本消息對象設(shè)計

Barry_Ng / 641人閱讀

摘要:基本消息對象的設(shè)計消息對象的設(shè)計主要由兩部分組成特定數(shù)據(jù)幀對應(yīng)的特定消息對象。該類包含上節(jié)數(shù)據(jù)幀主幀及子幀的所有公共信息,僅僅未包含子幀中的數(shù)據(jù)體信息,該需求由基本消息對象的子類實現(xiàn)。

開發(fā)工程中,有一個常見的需求:服務(wù)端程序和多個客戶端程序通過 TCP 協(xié)議進行通信,通信雙方需通信的消息種類眾多,并且客戶端的數(shù)量可能有數(shù)萬個。為此,雙方需要約定盡可能豐富、靈活的數(shù)據(jù)幀「數(shù)據(jù)包」協(xié)議,方便后續(xù)業(yè)務(wù)功能的設(shè)計。

本文設(shè)計了一種通信協(xié)議,為壓縮數(shù)據(jù)量,該協(xié)議的數(shù)據(jù)幀以二進制方式進行傳輸并識別,即其基本單位為字節(jié),必要時將部分字節(jié)流手動轉(zhuǎn)化為可讀文本。通過設(shè)定功能位來實現(xiàn)豐富的通信消息類型,并且采用注冊的方式,可方便擴展新的業(yè)務(wù)消息類型,可靈活地增刪通信消息對象。采用 Netty 框架保證高并發(fā)場景下程序的性能。

系統(tǒng)整體設(shè)計框圖如下:

1. 通信數(shù)據(jù)幀協(xié)議的設(shè)計 1.1 數(shù)據(jù)幀主幀的幀格式

首先給出通用的數(shù)據(jù)幀格式如下,一個數(shù)據(jù)幀主幀由:幀識別位、幀功能位、設(shè)備號、數(shù)據(jù)長度、數(shù)據(jù)體等 5 部分組成?!钙鋵嵶钔ㄓ玫臄?shù)據(jù)幀只有幀識別位,根據(jù)幀識別位確定幀類型,從而確定其余四個部分,本文中幀識別位固定,幀格式即固定了」

幀識別位:確定數(shù)據(jù)幀的開始,亦確定本幀的幀類型。

幀功能位:確定該幀所傳送的消息類型,特定的幀功能位對應(yīng)特定的數(shù)據(jù)體。

設(shè)備號:設(shè)備的識別號,服務(wù)端據(jù)此識別不同的客戶端。

數(shù)據(jù)長度:數(shù)據(jù)體所占用的字節(jié)數(shù)。

數(shù)據(jù)體:根據(jù)幀功能位,所確定的需傳輸?shù)木唧w的消息。

1.2 數(shù)據(jù)幀子幀的幀格式

數(shù)據(jù)幀除數(shù)據(jù)體以外的部分稱為幀頭,考慮這樣一種需求,如果某幀所要傳輸?shù)臄?shù)據(jù)體部分內(nèi)容很少,導(dǎo)致一個幀的大部分容量均被幀頭占據(jù),導(dǎo)致有效數(shù)據(jù)的占比很小,這就產(chǎn)生了巨大的浪費,舉例如下:

如一個開鎖幀,只需傳輸一個開鎖信號即可,消息的接收方、消息類型均體現(xiàn)在了幀頭中,數(shù)據(jù)部分只需要 0 個或 1 個字節(jié)即可。

客戶端需要向服務(wù)器發(fā)送自己的當(dāng)前狀態(tài)信息,該狀態(tài)信息可能也只需要 1 個字節(jié)左右。

由于如上實際的需求,如果增大了每一幀的有效數(shù)據(jù)的占比,整個通信鏈路的數(shù)據(jù)量會明顯減少,IO 負(fù)擔(dān)也會因此減輕,所以據(jù)此繼續(xù)對幀協(xié)議進行設(shè)計。

如上圖,對數(shù)據(jù)幀主幀中的「數(shù)據(jù)體」部分進行進一步拆分,數(shù)據(jù)幀主幀的數(shù)據(jù)體部分由子幀組成,子幀由:子幀功能位、數(shù)據(jù)長度、數(shù)據(jù)體等 3 部分組成。

子幀功能位:確定該子幀所傳送的消息類型,總而言之,主幀、子幀功能位共同確定了該子幀的消息類型。

數(shù)據(jù)長度:數(shù)據(jù)體所占用的字節(jié)數(shù)。

數(shù)據(jù)體:根據(jù)子幀功能位,所確定的需傳輸?shù)木唧w的消息。

1.3 數(shù)據(jù)幀的幀格式總覽

完整的幀格式如下圖所示,數(shù)據(jù)幀主幀的數(shù)據(jù)體部分完全由子幀組成,通信雙方通信時,可以往一個主幀中添加多個子幀,從而可以極大提高鏈路的使用效率。

2 數(shù)據(jù)幀處理模塊的實現(xiàn)

數(shù)據(jù)幀已進行了如上精心設(shè)計,將設(shè)計的數(shù)據(jù)幀通過程序?qū)崿F(xiàn)并投入實際使用才是最終目的。

2.1 數(shù)據(jù)幀處理的基本方法

以服務(wù)端的工作為例來進行說明。服務(wù)端程序監(jiān)聽指定端口,客戶端通過 TCP 協(xié)議向服務(wù)器發(fā)送二進制數(shù)據(jù)消息,服務(wù)端接收到二進制數(shù)據(jù)并進行處理,此處采用責(zé)任鏈模式,Netty 框架內(nèi)建了方便的基于責(zé)任鏈模式的消息處理方法:

第一個處理器將捕獲的數(shù)據(jù)截取為一個一個協(xié)議約定的數(shù)據(jù)幀并送入下層處理器,如果捕獲的二進制數(shù)據(jù)未符合協(xié)議約定的格式,則可以直接丟棄。「此處未考慮半包、粘包等場景」

第二個處理器捕獲到約定的數(shù)據(jù)幀,則著手對不同類型數(shù)據(jù)幀進行解析,解析為不同類型的 Java 消息對象,并將反序列化成功并驗證成功的 Java 對象送入下層處理器。如果上述過程失敗,可以認(rèn)為客戶端設(shè)計不合理,導(dǎo)致出現(xiàn)無效消息,直接丟棄該對象,也可以繼續(xù)通知服務(wù)端或客戶端該異常情況。

第三個處理器捕獲到正確的 Java 消息對象,則可以直接送入上層 Java 模塊進行處理,此處可根據(jù)不同的對象類型送入不同的上層處理模塊,或者在此處進行其他的工作「比如消息日志記錄工作等」。

2.2 基本 Java 消息對象的設(shè)計

Java 消息對象的設(shè)計主要由兩部分組成:

特定數(shù)據(jù)幀對應(yīng)的特定 Java 消息對象。

特定 Java 消息對象對應(yīng)的特定的該消息對象編解碼器。

以下是基本 Java 消息對象:

public abstract class BaseMsg implements Cloneable {

    private final BaseMsgCodec msgCodec;
    private int groupId;
    private int deviceId;
    private int resendTimes = 0;

    protected BaseMsg(BaseMsgCodec msgCodec, int groupId, int deviceId) {
        this.msgCodec = msgCodec;
        this.groupId = groupId;
        this.deviceId = deviceId;
    }

    /**
     * 獲取該消息對象的細(xì)節(jié)描述
     *
     * @return 該消息對象的細(xì)節(jié)描述
     */
    public String msgDetailToString() {
        return msgCodec.getDetail() +
                "[majorMsgId=" + Integer.toHexString(msgCodec.getMajorMsgId()).toUpperCase() +
                ", subMsgId=" + Integer.toHexString(msgCodec.getSubMsgId()).toUpperCase() +
                ", groupId=" + groupId +
                ", deviceId=" + deviceId + "]";
    }

    /**
     * 重發(fā)該消息對象的記錄信息更新
     */
    public void doResend() {
        resendTimes++;
    }
}

由上述代碼可知,每個消息對象均包含該對象對應(yīng)編解碼器的引用,方便獲取該消息對象的擴展信息,或者方便將該消息對象重新序列化為數(shù)據(jù)幀。該類包含上節(jié)數(shù)據(jù)幀主幀及子幀的所有公共信息,僅僅未包含子幀中的數(shù)據(jù)體信息,該需求由基本 Java 消息對象的子類實現(xiàn)。

該類由 abstract 修飾,是抽象類,無法直接實例化,具體的工作由該類的子類完成,即由具體的真正業(yè)務(wù)相關(guān)的 Java 消息對象完成。

以下為 Java 消息對象的基本編解碼器:

/**
 * 單個消息對象「幀」的編解碼器
 */
public abstract class BaseMsgCodec implements SubFramecoder, SubFramedecoder {

    private final int majorMsgId;
    private final int subMsgId;
    private final String detail;

    protected BaseMsgCodec(int majorMsgId, int subMsgId, String detail) {
        this.majorMsgId = majorMsgId;
        this.subMsgId = subMsgId;
        this.detail = detail;
    }

    public String getDetail() {
        return detail;
    }

    public int getMajorMsgId() {
        return majorMsgId;
    }

    public int getSubMsgId() {
        return subMsgId;
    }
}

由上述代碼可知,特定 Java 消息對象的編解碼器由數(shù)據(jù)幀的主幀、子幀功能位共同決定,這樣確保了消息編解碼器的規(guī)范,避免消息過多時的混亂。

Java 編解碼器實現(xiàn)了如下兩個接口,表明編解碼器可將 Java 消息對象編碼為數(shù)據(jù)幀,或?qū)?shù)據(jù)幀解碼為指定的 Java 消息對象:

public interface SubFramecoder {
    /**
     * 將 Java 消息對象編碼為數(shù)據(jù)幀
     *
     * @param msg    消息對象
     * @param buffer TCP 數(shù)據(jù)幀的容器
     * @return 生成的 TCP 數(shù)據(jù)幀的 ByteBuf
     */
    ByteBuf code(BaseMsg msg, ByteBuf buffer);
}

public interface SubFramedecoder {
    /**
     * 將數(shù)據(jù)幀解碼為指定的 Java 消息對象
     *
     * @param groupId  設(shè)備組 ID
     * @param deviceId 設(shè)備 ID
     * @param data     幀數(shù)據(jù)
     * @return 特定的 Java 消息對象
     */
    BaseMsg decode(int groupId, int deviceId, byte[] data);
}
相關(guān)項目參考「GitHub 項目基礎(chǔ)框架開源」

Java & Vue.js「集群設(shè)備管理云平臺『后端部分』」

基于 Vue.js 2.0 & Element 2.0 的集群設(shè)備管理云平臺

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68607.html

相關(guān)文章

  • 基于 Netty 插拔業(yè)務(wù)通信協(xié)議實現(xiàn)「2」特定業(yè)務(wù)消息對象設(shè)計

    摘要:而實際兩者之間的通信使用的是基于的自定義二進制數(shù)據(jù)幀,對象與數(shù)據(jù)幀之間需進行轉(zhuǎn)換。該類實現(xiàn)了編碼解碼方法,故可對消息對象進行編碼或?qū)?shù)據(jù)幀進行解碼。該類的靜態(tài)方法可通過指定功能消息對象生成相應(yīng)的回復(fù)對象。 本文為該系列的第二篇文章,設(shè)計需求為:服務(wù)端程序和眾多客戶端程序通過 TCP 協(xié)議進行通信,通信雙方需通信的消息種類眾多。上一篇文章詳細(xì)描述了該通信協(xié)議的二進制數(shù)據(jù)幀格式以及基本 J...

    Yuqi 評論0 收藏0
  • 基于 Netty 插拔業(yè)務(wù)通信協(xié)議實現(xiàn)「3」業(yè)務(wù)注冊實際工作流程

    摘要:本文仍以該實例為例,探討該自定義通信協(xié)議的具體工作流程,以及如何以注冊的形式靈活插拔通信消息對象。進行二進制數(shù)據(jù)幀的解碼操作時,數(shù)據(jù)幀中已包含了消息的功能位,據(jù)此可獲取相應(yīng)的編解碼器,而后可以對該數(shù)據(jù)幀進行解析,生成相應(yīng)的消息對象。 本文為該系列的第三篇文章,設(shè)計需求為:服務(wù)端程序和眾多客戶端程序通過 TCP 協(xié)議進行通信,通信雙方需通信的消息種類眾多。上一篇文章以一個具體的需求為例,...

    LdhAndroid 評論0 收藏0
  • Hyperledger Fabric(介紹)

    摘要:比特幣和以太幣屬于一類區(qū)塊鏈,我們將其歸類為公共無許可的區(qū)塊鏈技術(shù)。例如,在單個企業(yè)中部署時,或由受信任的權(quán)威機構(gòu)運作,完全拜占庭容錯的共識可能被認(rèn)為是不必要的,并且對性能和吞吐量造成過度的拖累。 介紹 一般而言,區(qū)塊鏈?zhǔn)且粋€不可變的交易分類賬,維護在一個分布式對等節(jié)點網(wǎng)絡(luò)中。這些節(jié)點通過應(yīng)用已經(jīng)由共識協(xié)議驗證的交易來維護分類帳的副本,該交易被分組為包括將每個塊綁定到前一個塊的散列的塊...

    yunhao 評論0 收藏0
  • Spring整合Netty、WebSocket互聯(lián)網(wǎng)聊天系統(tǒng)

    摘要:當(dāng)用戶注銷或退出時,釋放連接,清空對象中的登錄狀態(tài)。聊天管理模塊系統(tǒng)的核心模塊,這部分主要使用框架實現(xiàn),功能包括信息文件的單條和多條發(fā)送,也支持表情發(fā)送。描述讀取完連接的消息后,對消息進行處理。 0.前言 最近一段時間在學(xué)習(xí)Netty網(wǎng)絡(luò)框架,又趁著計算機網(wǎng)絡(luò)的課程設(shè)計,決定以Netty為核心,以WebSocket為應(yīng)用層通信協(xié)議做一個互聯(lián)網(wǎng)聊天系統(tǒng),整體而言就像微信網(wǎng)頁版一樣,但考慮...

    My_Oh_My 評論0 收藏0

發(fā)表評論

0條評論

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