12-netty基礎-手寫rpc-編解碼-04

?netty系列文章:

01-netty基礎-socket
02-netty基礎-java四種IO模型
03-netty基礎-多路復用select、poll、epoll
04-netty基礎-Reactor三種模型
05-netty基礎-ByteBuf數據結構
06-netty基礎-編碼解碼
07-netty基礎-自定義編解碼器
08-netty基礎-自定義序列化和反序列化
09-netty基礎-手寫rpc-原理-01
10-netty基礎-手寫rpc-定義協議頭-02
11-netty基礎-手寫rpc-支持多序列化協議-03
12-netty基礎-手寫rpc-編解碼-04
13-netty基礎-手寫rpc-消費方生成代理-05
14-netty基礎-手寫rpc-提供方(服務端)-06

1 自定義編輯碼

編解碼都采用原生的ByteBuf,分別為MessageToByteEncoder、ByteToMessageDecoder;解決了拆包、粘包問題
編碼:將需要發送的數據封裝成RpcProtocol形式進行發送
解碼:將接收到的數據解釋成RpcProtocol形式然后處理相應的業務邏輯

2 代碼

2.1 編碼

package com.bonnie.protocol.code;import com.alibaba.fastjson.JSONObject;
import com.bonnie.protocol.core.Header;
import com.bonnie.protocol.core.RpcProtocol;
import com.bonnie.protocol.serializer.ISerializer;
import com.bonnie.protocol.serializer.SerializerManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;/*** 編碼*/
@Slf4j
public class BonnieEncoder extends MessageToByteEncoder<RpcProtocol<Object>> {@Overrideprotected void encode(ChannelHandlerContext channelHandlerContext, RpcProtocol<Object> msg, ByteBuf out) throws Exception {log.info("============begin BonnieEncoder=========");Header header = msg.getHeader();// 魔數out.writeShort(header.getMagic());// 序列化類型out.writeByte(header.getSerialType());// 消息類型out.writeByte(header.getReqType());// 請求idout.writeLong(header.getRequestId());// 消息體序列化ISerializer serializer = SerializerManager.getSerializer(header.getSerialType());byte[] contentByteArray = serializer.serialize(msg.getContent());System.out.println("body長度"+contentByteArray.length);// 消息體長度,4個字節out.writeInt(contentByteArray.length);System.out.println("發送數據:"+JSONObject.toJSONString(msg));// 寫入消息體out.writeBytes(contentByteArray);}}

2.2 解碼

package com.bonnie.protocol.code;import com.bonnie.protocol.core.Header;
import com.bonnie.protocol.core.RpcProtocol;
import com.bonnie.protocol.core.RpcRequest;
import com.bonnie.protocol.core.RpcResponse;
import com.bonnie.protocol.enums.ReqTypeEnum;
import com.bonnie.protocol.enums.RpcConstant;
import com.bonnie.protocol.serializer.ISerializer;
import com.bonnie.protocol.serializer.SerializerManager;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;import java.util.List;
import java.util.Objects;/*** 解碼*/
@Slf4j
public class BonnieDecoder extends ByteToMessageDecoder {@Overrideprotected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {log.info("========begin BonnieDecoder==========");// 首先判斷可讀的字節是否小于頭的長度,如果小于,說明沒有body數據,甚至數據有問題,不解碼if (in.readableBytes()<= RpcConstant.HEAD_TOTOAL_LEN) {return;}// 標記讀取開始索引in.markReaderIndex();// 魔數short magic = in.readShort();if (!Objects.equals(magic, RpcConstant.MAGIC)) {throw new IllegalArgumentException("Illegal request parameter 'magic',"+magic);}// 序列化類型byte serialType = in.readByte();// 消息類型byte reqType = in.readByte();// 請求idlong requestId = in.readLong();// 報文長度int dataLength = in.readInt();// 可讀字節是否小于body的長度,如果小于,則不讀取,并且重置到讀指針的地方,等下一次讀if(in.readableBytes()<dataLength) {in.resetReaderIndex();return;}// 消息體byte[] bodyByteArray = new byte[dataLength];// body內容讀取到body中in.readBytes(bodyByteArray);// 封裝頭信息Header header = new Header();header.setMagic(magic);header.setSerialType(serialType);header.setReqType(reqType);header.setRequestId(requestId);header.setLength(dataLength);// 拿到對應的序列化ISerializer serializer = SerializerManager.getSerializer(serialType);/*** 根據請求類型,比如客戶端發送數據,就是REQUWST,服務端給客戶端回復數據就是RESPONSE,當然都是* 相對的,每一段都會發送REQUEST請求,每一段也會發送RESPONSE請求*/ReqTypeEnum reqTypeEnum = ReqTypeEnum.findByCode(reqType);switch (reqTypeEnum) {// 如果是請求報文  反序列化得到數據,封裝數據,繼續傳遞case REQUEST:RpcProtocol rpcProtocol = dealRequest(bodyByteArray, serializer, header);out.add(rpcProtocol);break;case RESPONSE:RpcProtocol rpcProtocolResponse = dealResponse(bodyByteArray, serializer, header);out.add(rpcProtocolResponse);break;case HEARTBEAT:// TODObreak;}}private RpcProtocol dealResponse(byte[] bodyByteArray, ISerializer serializer, Header header) {RpcResponse rpcResponse = serializer.deserialize(bodyByteArray, RpcResponse.class);RpcProtocol<RpcResponse> rpcProtocol = new RpcProtocol<>();rpcProtocol.setHeader(header);rpcProtocol.setContent(rpcResponse);return rpcProtocol;}private RpcProtocol dealRequest(byte[] bodyByteArray, ISerializer serializer, Header header) {RpcRequest rpcRequest = serializer.deserialize(bodyByteArray, RpcRequest.class);RpcProtocol<RpcRequest> rpcProtocol = new RpcProtocol<>();rpcProtocol.setHeader(header);rpcProtocol.setContent(rpcRequest);return rpcProtocol;}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92359.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92359.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92359.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決 Windows 下的“幽靈文件”——記一次與帶空格的 .gitignore 文件的艱難斗爭

引言 你是否遇到過這樣的情況&#xff1a;一個文件明明躺在你的文件夾里&#xff0c;ls 或 dir 命令都能清楚地看到它&#xff0c;但無論你用什么方法嘗試刪除&#xff0c;系統都冷酷地告訴你“找不到文件”&#xff1f; 就在今天&#xff0c;我就遇到了這樣一個“幽靈”般的 .…

(易視寶)易視TV is-E4-G-全志A20芯片-安卓4-燒寫卡刷工具及教程

&#xff08;易視寶&#xff09;易視TV is-E4-G-全志A20芯片-安卓4-燒寫卡刷工具及教程PhoenixCard_V309燒錄步驟&#xff1a;1、將TF或SD卡插入計算機&#xff0c;打開軟件&#xff1b;2、選擇固件所在目錄&#xff1b;3、燒寫模式選“卡量產”4、點擊“燒錄”開始量產&#x…

(數據結構)順序表實現-增刪查改

1.線性表 線性表(linear list)是n個具有相同特性的數據元素的有限序列。線性表是一種在實際中廣泛使用的數據結構,常見的線性表:順序表、鏈表、棧、隊列、字符串… 線性表在邏輯上是線性結構,也就說是連續的一條直線。但是在物理結構上并不一定是連續的,線性表在物理上存儲時…

【面試八股總結】線程/進程同步問題

一、同步與互斥 在線程并發執行的過程中&#xff0c;進程/線程之間存在協作的關系&#xff0c;例如有互斥、同步的關系。為了實現進程/線程間正確的協作&#xff0c;操作系統必須提供實現進程協作的措施和方法&#xff0c;主要的方法有兩種&#xff1a; 鎖&#xff1a;加鎖、解…

大語言模型提示工程與應用:提示工程入門指南

提示工程入門 學習目標 在本課程中&#xff0c;我們將學習提示工程。 相關知識點 提示工程 學習內容 1 提示工程 提示工程是一門新興學科&#xff0c;專注于設計和優化提示詞以高效利用語言模型完成多樣化任務。掌握提示工程能幫助開發者更深入理解大語言模型(LLM)的能力…

PostgreSQL 多級依賴血緣系統的設計與落地

一、業務背景&#xff1a;三類指標與四種狀態指標類型定義規則依賴關系原子指標單表聚合&#xff08;SELECT WHERE GROUP&#xff09;無派生指標在原子/派生指標上加 WHERE、改 GROUP依賴 1~N 個父指標復合指標多個原子/派生指標做加減運算依賴 1~N 個父指標狀態說明已保存草…

阿里云百煉平臺創建智能體-上傳文檔

整體思路是&#xff1a; 1創建ram用戶&#xff0c;授權 2上傳文件獲取FileSession 3調用智能體對話&#xff0c;傳入FileSession 接下來每個步驟的細節&#xff1a; 1官方不推薦使用超級管理員用戶獲得accessKeyId和accessKeySecret&#xff0c;所以登錄超級管理員賬號創建…

剪映里面導入多張照片,p圖后如何再導出多張照片?

剪映普通版本暫時沒發現可以批量導出圖片。這里采用其他方式實現。先整體導出視頻。這里前期要注意設置幀率&#xff0c;一張圖片的時長。 參考一下設置&#xff0c;幀率設置為30&#xff0c;圖片導入時長設置為1s&#xff0c;這樣的話&#xff0c;方便后期把視頻切割為單幀。導…

怎么查看Linux I2C總線掛載了那些設備?

1. 根據系統啟動查看設備樹節點文件&#xff08;系統運行后的&#xff09; 比如&#xff1a;要查看I2C2i2c2: i2cfeaa0000 {compatible "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";reg <0x0 0xfeaa0000 0x0 0x1000>;clocks <&cru CLK_…

bat腳本實現獲取非微軟官方服務列表

Get-CimInstance -ClassName Win32_Service |Where-Object { $_.State -eq Running -and $_.StartMode -ne Disabled } | ForEach-Object {$isMicrosoft $false$signerInfo 無可執行路徑if ($_.PathName) {# 提取可執行文件路徑&#xff08;處理帶引號/參數的路徑&#xff09…

小程序難調的組件

背景。做小程序用到了自定義表單。前后端都是分開寫的&#xff0c;沒有使用web-view。所以要做到功能對稱時間選擇器。需要區分datetime, year, day等類型使用uview組件較方便 <template><view class"u-date-picker" v-if"visible"><view c…

從零構建TransformerP2-新聞分類Demo

歡迎來到啾啾的博客&#x1f431;。 記錄學習點滴。分享工作思考和實用技巧&#xff0c;偶爾也分享一些雜談&#x1f4ac;。 有很多很多不足的地方&#xff0c;歡迎評論交流&#xff0c;感謝您的閱讀和評論&#x1f604;。 目錄引言1 一個完整的Transformer模型2 需要準備的“工…

qt qml實現電話簿 通訊錄

qml實現電話簿&#xff0c;基于github上開源代碼修改而來&#xff0c;增加了搜索和展開&#xff0c;效果如下 代碼如下 #include <QGuiApplication> #include <QQmlApplicationEngine>int main(int argc, char *argv[]) {QCoreApplication::setAttribute(Qt::AA_…

順序表——C語言

順序表實現代碼解析與學習筆記一、順序表基礎概念順序表是線性表的一種順序存儲結構&#xff0c;它使用一段連續的內存空間&#xff08;數組&#xff09;存儲數據元素&#xff0c;通過下標直接訪問元素&#xff0c;具有隨機訪問的特性。其核心特點是&#xff1a;元素在內存中連…

【Oracle篇】Oracle Data Pump遠程備份技術:直接從遠端數據庫備份至本地環境

&#x1f4ab;《博主主頁》&#xff1a;    &#x1f50e; CSDN主頁__奈斯DB    &#x1f50e; IF Club社區主頁__奈斯、 &#x1f525;《擅長領域》&#xff1a;擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控&#xff1b;并對…

Linux系統--文件系統

大家好&#xff0c;我們今天繼續來學習Linux系統部分。上一次我們學習了內存級的文件&#xff0c;下面我們來學習磁盤級的文件。那么話不多說&#xff0c;我們開始今天的學習&#xff1a; 目錄 Ext系列?件系統 1. 理解硬件 1-1 磁盤、服務器、機柜、機房 1-2 磁盤物理結構…

KUKA庫卡焊接機器人氬氣節氣設備

在焊接生產過程中&#xff0c;氬氣作為一種重要的保護氣體被廣泛應用于KUKA庫卡焊接機器人的焊接操作中。氬氣的消耗往往是企業生產成本的一個重要組成部分&#xff0c;因此實現庫卡焊接機器人節氣具有重要的經濟和環保意義。WGFACS節氣裝置的出現為解決這一問題提供了有效的方…

遠程連接----ubuntu ,rocky 等Linux系統,WindTerm_2.7.0

新一代開源免費的終端工具-WindTerm github 27.5k? https://github.com/kingToolbox/WindTerm/releases/download/2.7.0/WindTerm_2.7.0_Windows_Portable_x86_64.zip 主機填寫你自己要連接的主機ip 端口默認 22 改成你ssh文件配置的端口 輸入遠程的 用戶名 與密碼 成功連接…

筆試——Day32

文章目錄第一題題目思路代碼第二題題目&#xff1a;思路代碼第三題題目&#xff1a;思路代碼第一題 題目 素數回文 思路 模擬 構建新的數字&#xff0c;判斷該數是否為素數 代碼 第二題 題目&#xff1a; 活動安排 思路 區間問題的貪?&#xff1a;排序&#xff0c;然…

超高車輛如何影響城市立交隧道安全?預警系統如何應對?

超高車輛對立交隧道安全的潛在威脅在城市立交和隧道中&#xff0c;限高設施的設計通常考慮到大部分正常通行的貨車和運輸車輛。然而&#xff0c;一些超高的貨車、集裝箱車或特殊車輛如果未經有效監測而進入限高區域&#xff0c;就可能對道路設施造成極大的安全隱患。尤其在立交…