likes
comments
collection
share

Netty实现RPC之消息对象构建从本文开始,将逐步对该技术项目进行讲解,并在过程中引申、深度讲解Netty的核心知识,

作者站长头像
站长
· 阅读数 26

Netty实现RPC之消息对象构建

前言

本篇是用Netty实现一个RPC中间件的开篇,未来还会持续更新,代码在最后一片更新完毕之后将会上传到github、gitee代码托管平台,供大家拉取学习,并进行讨论分享,让该RPC框架持续精进。

需要声明的是该RPC中间件借鉴于gitee作者:芜湖呆头鹅,具体项目:netty手写rpc框架

从本文开始,将逐步对该技术项目进行讲解,并在过程中引申、深度讲解Netty的核心知识,和大家一起对Java并发和网络编程领域的皇冠Netty进行知人知面又知心式的了解,让大家在该领域拥有坚实的知识底座。

愿我们在技术的浩瀚中游刃有余。

项目基本概览

软件架构

此处准备分模块进行编写,便于后期的SPI模式下的依赖构建。

Netty实现RPC之消息对象构建从本文开始,将逐步对该技术项目进行讲解,并在过程中引申、深度讲解Netty的核心知识,

执行流程

Netty实现RPC之消息对象构建从本文开始,将逐步对该技术项目进行讲解,并在过程中引申、深度讲解Netty的核心知识,

核心流程图

Netty实现RPC之消息对象构建从本文开始,将逐步对该技术项目进行讲解,并在过程中引申、深度讲解Netty的核心知识,

消息构建

通过构建一个抽象消息类来进一步规范后续的消息,核心代码如下所示:

package cn.org.xiaosheng.core.message;

import lombok.Data;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * @author XiaoSheng
 * @date 2024/8/20 下午10:24
 */
@Data
public abstract class Message implements Serializable {

    /**
     * 存储 k:消息类型 v:消息Class 键值对
     */
    private static final Map<Integer, Class<? extends Message>> messageClasses = new HashMap<>();

    // 消息类型
    public static final int PingMessage = 14;
    public static final int PongMessage = 15;
    /**
     * 请求类型 byte 值
     */
    public static final int RPC_MESSAGE_TYPE_REQUEST = 101;
    /**
     * 响应类型 byte 值
     */
    public static final int  RPC_MESSAGE_TYPE_RESPONSE = 102;

    static {
        messageClasses.put(RPC_MESSAGE_TYPE_REQUEST, RpcRequestMessage.class);
        messageClasses.put(RPC_MESSAGE_TYPE_RESPONSE, RpcResponseMessage.class);
        messageClasses.put(PingMessage, PingMessage.class);
        messageClasses.put(PongMessage, PongMessage.class);
    }

    /**
     * 根据消息类型字节,获得对应的消息 class
     * @param messageType 消息类型字节
     * @return 消息 class
     */
    public static Class<? extends Message> getMessageClass(int messageType) {
        return messageClasses.get(messageType);
    }

    // 消息唯一编号
    private int sequenceId;

    // 消息类型
    private int messageType;

    /**
     * 获取消息类型
     * @return
     */
    public abstract int getMessageType();


}

下面针对上面的Message的各部分进行深度讲解:

  • messageClasses : 存储k: 消息对象 v: 消息对象Class, 一个存储容器,并且在Message进行加载时就将各消息类型:消息对象Class装载到容器中,供后续调用。
  • getMessageClass(int messageType) : 通过消息类型获取对应的消息Class对象。
  • sequenceId: 消息的唯一编号,每个消息都会有一个消息唯一编号,后续的发送、收取都将根据该唯一编号进行处理。
  • messageType: 消息类型
  • getMessageType(): 供后续各消息子类实现,返回自身消息类型。
  • 各消息类型常量均放置在Message类中。

心跳消息

PingMessage

/**
 * @author XiaoSheng
 * @date 2024/8/20 下午10:27
 */
public class PingMessage extends Message{

    @Override
    public int getMessageType() {
        return PingMessage;
    }
}

PongMessage

/**
 * @author XiaoSheng
 * @date 2024/8/20 下午10:27
 */
public class PongMessage extends Message {
    @Override
    public int getMessageType() {
        return PongMessage;
    }
}

RPC消息

RpcRequestMessage

/**
 * @author XiaoSheng
 * @date 2024/8/20 下午10:27
 */
@Data
@ToString(callSuper = true)
public class RpcRequestMessage extends Message{


    /**
     * 调用的服务类简单类名,服务端根据它找到实现
     */
    private String serviceName;

    /**
     * 调用服务类中的方法名
     */
    private String methodName;

    /**
     * 方法返回类型
     */
    private Class<?> returnType;

    /**
     * 方法参数类型数组
     */
    private Class[] parameterTypes;

    /**
     * 方法参数值数组
     */
    private Object[] parameterValue;


    public RpcRequestMessage(int sequenceId, String serviceName, String methodName, Class<?> returnType, Class[] parameterTypes, Object[] parameterValue) {
        super.setSequenceId(sequenceId);
        this.serviceName = serviceName;
        this.methodName = methodName;
        this.returnType = returnType;
        this.parameterTypes = parameterTypes;
        this.parameterValue = parameterValue;
    }

    @Override
    public int getMessageType() {
        return RPC_MESSAGE_TYPE_REQUEST;
    }
}

RpcReponseMessage

/**
 * @author XiaoSheng
 * @date 2024/8/20 下午10:27
 */
@Data
@ToString(callSuper = true)
public class RpcResponseMessage extends Message {

    /**
     * 消息调用返回值
     */
    private Object returnValue;
    /**
     * 消息调用异常值
     */
    private Exception exceptionValue;


    @Override
    public int getMessageType() {
        return RPC_MESSAGE_TYPE_RESPONSE;
    }
}

最后

该系统的消息构建就如上述所述,心跳消息、RPC消息是本系统的消息核心,下一篇将讲述自定义协议构建,本系统的所有代码将附在最后一篇博文中,供大家拉取学习。

转载自:https://juejin.cn/post/7406482061731315731
评论
请登录