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

資訊專欄INFORMATION COLUMN

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

Yuqi / 2087人閱讀

摘要:而實際兩者之間的通信使用的是基于的自定義二進制數(shù)據(jù)幀,對象與數(shù)據(jù)幀之間需進行轉(zhuǎn)換。該類實現(xiàn)了編碼解碼方法,故可對消息對象進行編碼或?qū)?shù)據(jù)幀進行解碼。該類的靜態(tài)方法可通過指定功能消息對象生成相應(yīng)的回復(fù)對象。

本文為該系列的第二篇文章,設(shè)計需求為:服務(wù)端程序和眾多客戶端程序通過 TCP 協(xié)議進行通信,通信雙方需通信的消息種類眾多。上一篇文章詳細描述了該通信協(xié)議的二進制數(shù)據(jù)幀格式以及基本 Java 消息類,假設(shè)通信雙方「服務(wù)端、客戶端」均由 Netty 框架構(gòu)建而成,雙方在程序內(nèi)部使用 Java 消息對象,通信雙方信息交互采用的是自定義二進制幀格式,本文通過一個具體實例,探討指定的 Java 消息對象與其相應(yīng)的二進制數(shù)據(jù)幀相互轉(zhuǎn)換的方法。

1 特定 Java 消息對象通信舉例

本小節(jié)以一個具體的需求為例,講述該自定義通信協(xié)議的工作流程。該需求為:對某一個特定的客戶端進行命名。該需求的具體工作流程描述如下:

服務(wù)端需主動向指定的客戶端發(fā)送消息,對客戶端設(shè)置指定的名稱,客戶端接到指定的消息并驗證合法后,需向服務(wù)端反饋消息接受成功的確認回復(fù),服務(wù)器接收到該回復(fù)后,即可認為對客戶端進行命名的消息發(fā)送成功并且名字設(shè)置成功,若服務(wù)端在指定的時間內(nèi)未收到回復(fù),需進行重發(fā)或者向上層「如管理員或數(shù)據(jù)庫」反饋該客戶端的異常。

上述過程使用 UML 序列圖演示如下:

由上圖可以直觀地看出:管理員對服務(wù)器的操作以及服務(wù)器對管理員的反饋均為動作,Server 與 Client 之間的通信以 Java 的視角均通過 Java 消息對象,共需兩個對象:客戶端別名設(shè)置對象、客戶端別名設(shè)置回復(fù)對象。而實際兩者之間的通信使用的是基于 TCP 的自定義二進制數(shù)據(jù)幀,對象與數(shù)據(jù)幀之間需進行轉(zhuǎn)換。

2 該任務(wù)所需 Java 消息類的設(shè)計

上小節(jié)所述過程需要兩個 Java 消息類,如下所示:

客戶端別名設(shè)置類

/**
 * 「消息對象」客戶端別名設(shè)置
 */
public class MsgDeviceName extends BaseMsg {

    private final String name;

    public MsgDeviceName(BaseMsgCodec msgCodec, int groupId, int deviceId, String name) {
        super(msgCodec, groupId, deviceId);
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String msgDetailToString() {
        return super.msgDetailToString() + "別名:" + name;
    }
}

客戶端別名設(shè)置回復(fù)類「直接使用通用回復(fù)類」

/**
 * 「消息對象」通用消息回復(fù)
 */
public class MsgReplyNormal extends BaseMsg {

    public MsgReplyNormal(BaseMsgCodec msgCodec, int groupId, int deviceId) {
        super(msgCodec, groupId, deviceId);
    }

    @Override
    public String msgDetailToString() {
        return super.msgDetailToString();
    }
}

客戶端別名設(shè)置類相比于基礎(chǔ)消息類,覆寫了消息細節(jié)描述方法,優(yōu)化調(diào)試日志的使用體驗。主要改變是,僅僅增加了客戶端別名的引用及其 Get 方法;而對于客戶端別名設(shè)置回復(fù),直接使用了通用回復(fù)類,減小了設(shè)計的復(fù)雜度。

該自定義幀協(xié)議有一個設(shè)計要點:每一個功能性消息類均有相對應(yīng)的特定回復(fù)類。從功能位的角度來看,該兩種類的主幀功能位之間存在如下關(guān)系:

消息回復(fù)類功能位 - 消息類功能位 = 0x10

即兩類的功能位數(shù)值之差以十六進制表示為 0x10。據(jù)此設(shè)計功能性 Java 消息類后,不需要專門設(shè)計對應(yīng)的回復(fù)類,系統(tǒng)會自行使用該通用回復(fù)類進行工作。

3 該任務(wù)所需消息類編解碼器的設(shè)計

編碼器可將 Java 消息對象編碼為數(shù)據(jù)幀,解碼器可講數(shù)據(jù)幀解碼為指定的 Java 消息對象,上節(jié)所述的兩種消息類均需要相對應(yīng)的編解碼器,如下所示:

3.1 客戶端別名設(shè)置編解碼器類

該類相比于基礎(chǔ)類,新增了編解碼器的靜態(tài)工廠方法,手動傳入功能位及功能文字描述,進而生成包含這些參數(shù)的編解碼器。如此設(shè)計,使得所有消息的功能位和文字描述均能夠統(tǒng)一管理,降低維護成本。

該類實現(xiàn)了編碼、解碼方法,故可對消息對象進行編碼或?qū)?shù)據(jù)幀進行解碼。該類的實現(xiàn)如下所示:

/**
 * 「消息對象編解碼器」客戶端別名設(shè)置
 */
public class MsgCodecDeviceName extends BaseMsgCodec {

    private static MsgCodecDeviceName msgCodec = null;

    public MsgCodecDeviceName (int majorMsgId, int subMsgId, String detail) {
        super(majorMsgId, subMsgId, detail);
        msgCodec = this;
    }

    public static MsgDeviceName create(int groupId, int deviceId, String name) {
        return new MsgDeviceName(msgCodec, groupId, deviceId, name);
    }

    @Override
    public ByteBuf code(BaseMsg msg, ByteBuf buffer) {
        MsgDeviceName message = (MsgDeviceName) msg;
        buffer.writeByte(message.getSubMsgId());
        byte[] data = KyToArrayUtil.stringToArray(message.getName());
        buffer.writeShort(data.length);
        buffer.writeBytes(data);
        return buffer;
    }

    @Override
    public MsgDeviceName decode(int groupId, int deviceId, byte[] data) {
        String name = KyToArrayUtil.arrayToString(data);
        return create(groupId, deviceId, name);
    }
}
3.2 通用回復(fù)編解碼器類

該類相比于基礎(chǔ)類,新增了編解碼器的靜態(tài)工廠方法,實現(xiàn)了編解碼器,理由與上小節(jié)相同。該類的 createByBaseMsg(BaseMsg) 靜態(tài)方法可通過指定功能消息對象生成相應(yīng)的回復(fù)對象。該類的實現(xiàn)如下所示:

/**
 * 「消息對象編解碼器」通用消息回復(fù)
 */
public class MsgCodecReplyNormal extends BaseMsgCodec {

    private static MsgCodecReplyNormal msgCodec = null;

    public MsgCodecReplyNormal(int majorMsgId, int subMsgId, String detail) {
        super(majorMsgId, subMsgId, detail);
        msgCodec = this;
    }

    /**
     * 根據(jù)收到的消息對象,創(chuàng)建新的通用消息回復(fù)對象,
     *
     * @param msg 收到的消息對象
     * @return 新的通用消息回復(fù)對象
     */
    public static MsgReplyNormal createByBaseMsg(BaseMsg msg) {
        BaseMsgCodec msgCodec = MsgCodecToolkit.getMsgCodec(msg.getMajorMsgId() + 0x10, msg.getSubMsgId());
        if (msgCodec == null) {
            return null;
        }
        return new MsgReplyNormal(msgCodec, msg.getGroupId(), msg.getDeviceId());
    }

    /**
     * 創(chuàng)建新的通用消息回復(fù)對象
     *
     * @param groupId  組號
     * @param deviceId 設(shè)備號
     * @return 生成的通用消息回復(fù)對象
     */
    private MsgReplyNormal create(int groupId, int deviceId) {
        return new MsgReplyNormal(this, groupId, deviceId);
    }

    @Override
    public ByteBuf code(BaseMsg msg, ByteBuf buffer) {
        MsgReplyNormal message = (MsgReplyNormal) msg;
        buffer.writeByte(message.getSubMsgId());
        buffer.writeShort(0);
        return buffer;
    }

    @Override
    public MsgReplyNormal decode(int groupId, int deviceId, byte[] data) {
        return create(groupId, deviceId);
    }
}

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

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

相關(guān)文章

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

    摘要:基本消息對象的設(shè)計消息對象的設(shè)計主要由兩部分組成特定數(shù)據(jù)幀對應(yīng)的特定消息對象。該類包含上節(jié)數(shù)據(jù)幀主幀及子幀的所有公共信息,僅僅未包含子幀中的數(shù)據(jù)體信息,該需求由基本消息對象的子類實現(xiàn)。 開發(fā)工程中,有一個常見的需求:服務(wù)端程序和多個客戶端程序通過 TCP 協(xié)議進行通信,通信雙方需通信的消息種類眾多,并且客戶端的數(shù)量可能有數(shù)萬個。為此,雙方需要約定盡可能豐富、靈活的數(shù)據(jù)幀「數(shù)據(jù)包」協(xié)議,...

    Barry_Ng 評論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
  • 基于 Webpack4 插拔式微前端架構(gòu) - Puzzle

    項目地址 showImg(https://segmentfault.com/img/remote/1460000019380071); 什么是 Puzzle Puzzle 是基于 Vue 和 Webpack4 實現(xiàn)的一種項目結(jié)構(gòu);業(yè)務(wù)模塊可以像拼圖一樣與架構(gòu)模塊組合,形成不同的系統(tǒng),而這一切都是可以在生產(chǎn)環(huán)境熱插拔的;這意味著你可以隨時向你的系統(tǒng)添加新的功能模塊,甚至改版整個系統(tǒng),而不需要全量替換...

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

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

    yunhao 評論0 收藏0

發(fā)表評論

0條評論

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