【BlossomRPC】编解码器的实现

2024-03-31 05:52

本文主要是介绍【BlossomRPC】编解码器的实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

RPC项目

配置中心项目

网关项目

在前面的文章了解完毕之后,我们以及设计了一个基本的RPC协议,之后,我们要做的就是基于这个RPC协议,去实现一个能解析这个RPC协议的编解码器。

这里编解码器比较容易写,按照前面几篇文章中讲解的方式来编写即可。

@Slf4j
public class RpcEncode extends MessageToByteEncoder<RpcDto<Object>> {@Overrideprotected void encode(ChannelHandlerContext ctx, RpcDto<Object> msg, ByteBuf out) throws Exception {log.info("Start encoding the data");//判断请求头合法性if (Objects.isNull(msg)) {log.warn("the RpcDto msg is Null!!!");return;}RpcHeader RpcHeader=msg.getHeader();out.writeByte(RpcHeader.getVersionId());out.writeByte(RpcHeader.getAlgorithmType());out.writeByte(RpcHeader.getReqType());out.writeLong(RpcHeader.getReqId());//设定序列化算法Serializer serializer= SerializerStrategy.getSerializer(RpcHeader.getAlgorithmType());byte[] data=serializer.serialize(msg.getData());//设定数据长度out.writeInt(data.length);//设定数据out.writeBytes(data);}
}

解码器的代码也并不难写,我们不断的从bytebuf中读取数据即可,然后最后还原为RpcDto对象即可。

package blossom.project.rpc.core.netty.codec;import blossom.project.rpc.common.constants.RpcCommonConstants;
import blossom.project.rpc.common.enums.ReqTypeEnum;
import blossom.project.rpc.core.entity.RpcDto;
import blossom.project.rpc.core.entity.RpcHeader;
import blossom.project.rpc.core.entity.RpcRequest;
import blossom.project.rpc.core.entity.RpcResponse;
import blossom.project.rpc.core.serialize.Serializer;
import blossom.project.rpc.core.serialize.SerializerStrategy;
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;/*** @author: ZhangBlossom* @date: 2023/12/16 18:58* @contact: QQ:4602197553* @contact: WX:qczjhczs0114* @blog: https://blog.csdn.net/Zhangsama1* @github: https://github.com/ZhangBlossom* RpcDecode类* 平平无奇RPC自定义协议的解码器*/
@Slf4j
public class RpcDecode extends ByteToMessageDecoder {@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {log.info("Start decoding the data");//判断请求头合法性if (Objects.isNull(in)) {log.warn("the data is Null!!!");return;}//因为我们的数据至少包含请求头+请求体 因此长度小于此肯定有问题if (in.readableBytes() < RpcCommonConstants.HEADER_LENGTH) {log.warn("The length of the request header does not meet the requirements!!!");return;}//读取版本号byte versionId = in.readByte();if (versionId != RpcCommonConstants.VERSION_ID) {throw new IllegalArgumentException("Illegal versionId!!!");}//继续读取请求头信息byte algorithmType = in.readByte();byte reqType = in.readByte();long reqId = in.readLong();int length = in.readInt();//判断可读长度是否小于请求头中设定的请求体长度if (in.readableBytes() < length) {//数据长度不对劲 先丢掉log.info("the readable bytes's length is less!!!");return;}RpcHeader header = new RpcHeader(versionId, algorithmType, reqType, reqId, length);//获得反序列化器Serializer serializer = SerializerStrategy.getSerializer(algorithmType);//获得请求类型ReqTypeEnum reqTypeEnum = ReqTypeEnum.getReqTypeByCode(reqType);//得到实际传输的数据byte[] data = new byte[length];in.readBytes(data);RpcDto dto = null;switch (reqTypeEnum) {case REQUEST:// 处理 GET 请求逻辑log.info("Handling REQUEST request");RpcRequest request =serializer.deserialize(data, RpcRequest.class);dto = new RpcDto<RpcRequest>();dto.setHeader(header);dto.setData(request);//设定到out中 会自动被handler处理out.add(dto);break;case RESPONSE:// 处理 RESPONSE 请求逻辑log.info("Handling RESPONSE request");RpcResponse response =serializer.deserialize(data, RpcResponse.class);dto = new RpcDto<RpcResponse>();dto.setHeader(header);dto.setData(response);//设定到out中 会自动被handler处理out.add(dto);break;case HEARTBEAT:// 处理心跳检测逻辑log.info("Handling HEARTBEAT request");break;default:log.warn("Unsupported request type: " + reqTypeEnum);}}
}

编解码器我们就写完了,接下来我们先不编写Handler,因为其实从上到下,Handler最终的设计思路还没办法那么快确定。
我们先去编写一个Server端和Client端。
然后设计一下我们希望的RPC调用方式。
这里我们参考dubbo的实现。

这篇关于【BlossomRPC】编解码器的实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/863565

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到