从零学习Hession RPC

为什么学习Hessian RPC?

  • 存粹的RPC,只解决PRC的四个核心问题(1.网络通信2.协议 3.序列化 4.代理)
  • Java写的
  • HessianRPC落伍了,但是它的序列化方式还保存着,被Dubbo(Hessian Lite)使用。
    被落伍,只是因为Hessian RPC出的比较早,当时没有注册中心,熔断,限流等。所以当我们学习PRC时,最好学一个简单的,存粹的,没有其他的额外功能。

Hessian 的概念

Hession 是Resin服务器的伴生产品。基于Java编程语言设计的RPC框架,只支持Java编程语言使用,现在新出的gRPC Thrift,支持多语言。Hessian的序列化是二进制的。

Hessian设计思想

Hessian使用的resin服务器,类似于Tomcat,使用的是HTTP协议,由于使用的是JDK做代理,所以必须要用接口定义调用类。对象的数据类型,必须要实现Serliazble。服务的发布需要使用HessanServlet进行配置,在web.xml进行配置。

那么如何进行调用配置的服务,客户端进行代理,HessianProxyFactory做代理服务。

RPC的开发

引入依赖

java 复制代码
<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.9</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>

        <dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId>
            <version>4.0.38</version>
        </dependency>
</dependencies>

开发服务端

java 复制代码
1. 开发Service
2. DAO --- Mybaits
注意:一定要定义Service的接口,自定义的数据类型实现Serliazliable

模拟一下登录功能:

实体类

java 复制代码
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private String password;
}

Service

java 复制代码
public interface UserService {
    public boolean login(String username,String password);

    public void register(User user);

}

ServrceImpl

java 复制代码
@Slf4j
public class UserServiceImpl implements UserService {
    @Override
    public boolean login(String username, String password) {
        log.debug("login method invoke name {} password {}",username,password);
        return false;
    }

    @Override
    public void register(User user) {
        log.debug("register method invoke user {}",user);
    }
}

配置web.xml

xml 复制代码
 <servlet>
        <servlet-name>userServiceRPC</servlet-name>
        <servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
        <init-param>
            <param-name>home-api</param-name>
            <param-value>com.liu.service.UserService</param-value>
        </init-param>
        <init-param>
            <param-name>home-class</param-name>
            <param-value>com.liu.service.UserServiceImpl</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>userServiceRPC</servlet-name>
        <url-pattern>/userServiceRPC</url-pattern>
    </servlet-mapping>

客户端开发

java 复制代码
@Slf4j
public class HessianRPCClient {
    public static void main(String[] args) throws MalformedURLException {
        // TODO
        HessianProxyFactory factory = new HessianProxyFactory();

        String urlName = "http://localhost:8080/rpc_hessian/userServiceRPC";
        UserService userService = (UserService) factory.create(UserService.class, urlName);
        boolean login = userService.login("liu", "123456");
        log.debug("userService value is {}",login);

    }
}

HessianRPC核心源码分析

java 复制代码
1. HessianRPC client创建代理的方式 JDK Proxy.newProxyInstance()
   public Object create(Class<?> api, URL url, ClassLoader loader){
    if (api == null)
      throw new NullPointerException("api must not be null for HessianProxyFactory.create()");
    InvocationHandler handler = null;

    handler = new HessianProxy(url, this, api);

    return Proxy.newProxyInstance(loader,
                                  new Class[] { api,
                                                HessianRemoteObject.class },
                                  handler);
  }

2. 代理中   
     通过网络 Http请求 连接 远端RPC服务
     通过流 数据写出去了。
   HessianProxy#invoke()  
     1.通过 URLConnection 进行网络连接 
     2.解析协议 传递数据

Hessian序列化

前面说了,Hessian已经落伍了,但他的序列化方式还保留着,我们看看怎么使用的。

java 复制代码
  // 1. 序列化
        OutputStream  outputStream = new FileOutputStream("D:\\StudyCodes\\rpc_lession\\rpc_hessian\\test");
        Hessian2Output hessian2Output = new Hessian2Output(outputStream);
        hessian2Output.writeObject(new User("liu", "123456"));
        hessian2Output.flush();
        outputStream.close();
        // 2. 反序列化
        InputStream inputStream = new FileInputStream("D:\\StudyCodes\\rpc_lession\\rpc_hessian\\test");
        Hessian2Input hessian2Input = new Hessian2Input(inputStream);
        User user = (User) hessian2Input.readObject();
        System.out.println(user);
        inputStream.close();
        log.info("user: {}", user);
相关推荐
anddddoooo3 小时前
域内证书维权
服务器·网络·网络协议·安全·网络安全·https·ssl
mit6.8243 小时前
[实现Rpc] 通信-Muduo库的实现 | && 完美转发 | reserve | unique_lock
c++·网络协议·rpc
IsToRestart4 小时前
什么是RPC,和HTTP有什么区别?
网络协议·http·rpc
okok__TXF4 小时前
Rpc导读
网络·网络协议·rpc
陈无左耳、4 小时前
HarmonyOS学习第3天: 环境搭建开启鸿蒙开发新世界
学习·华为·harmonyos
柃歌4 小时前
【UCB CS 61B SP24】Lecture 7 - Lists 4: Arrays and Lists学习笔记
java·数据结构·笔记·学习·算法
柃歌4 小时前
【UCB CS 61B SP24】Lecture 4 - Lists 2: SLLists学习笔记
java·数据结构·笔记·学习·算法
猫猫的小茶馆5 小时前
【网络编程】UDP协议
linux·服务器·网络·网络协议·ubuntu·udp
虾球xz5 小时前
游戏引擎学习第115天
学习·游戏引擎
BUG 劝退师6 小时前
C语言预处理学习笔记
c语言·笔记·学习