成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

Yuqi / 2137人閱讀

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

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

1 特定 Java 消息對(duì)象通信舉例

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

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

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

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

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

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

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

/**
 * 「消息對(duì)象」客戶端別名設(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ù)類」

/**
 * 「消息對(duì)象」通用消息回復(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ǔ)消息類,覆寫了消息細(xì)節(jié)描述方法,優(yōu)化調(diào)試日志的使用體驗(yàn)。主要改變是,僅僅增加了客戶端別名的引用及其 Get 方法;而對(duì)于客戶端別名設(shè)置回復(fù),直接使用了通用回復(fù)類,減小了設(shè)計(jì)的復(fù)雜度。

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

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

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

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

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

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

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

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

/**
 * 「消息對(duì)象編解碼器」客戶端別名設(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)工廠方法,實(shí)現(xiàn)了編解碼器,理由與上小節(jié)相同。該類的 createByBaseMsg(BaseMsg) 靜態(tài)方法可通過指定功能消息對(duì)象生成相應(yīng)的回復(fù)對(duì)象。該類的實(shí)現(xiàn)如下所示:

/**
 * 「消息對(duì)象編解碼器」通用消息回復(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ù)收到的消息對(duì)象,創(chuàng)建新的通用消息回復(fù)對(duì)象,
     *
     * @param msg 收到的消息對(duì)象
     * @return 新的通用消息回復(fù)對(duì)象
     */
    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ù)對(duì)象
     *
     * @param groupId  組號(hào)
     * @param deviceId 設(shè)備號(hào)
     * @return 生成的通用消息回復(fù)對(duì)象
     */
    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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/71070.html

相關(guān)文章

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

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

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

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

    LdhAndroid 評(píng)論0 收藏0
  • 基于 Webpack4 插拔式微前端架構(gòu) - Puzzle

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

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

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

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

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

0條評(píng)論

閱讀需要支付1元查看
<