Hessian RPC -快速入门

81 阅读2分钟

参考up:孙哥
孙哥主页

为什么要学习这个比较老的RPC框架

  1. 纯粹的RPC,只解决了RPC的四个核心问题

    1. 网络通信
    2. 协议
    3. 序列化
    4. 代理
  2. Java写的

  3. Hessian RPC落伍了,但是他的序列化方式 Dubbo还在使用

     Dubbo用的Hessian,阿里定制(Hessain Lite) Dubbo默认启动
    

Hessian RPC 概念

  1. Resin 服务器的伴生产品
  2. 基于Java编程语言设计的RPC框架,只支持Java编程语言使用(服务调用者和提供者都得是Java开发)
  3. 序列化协议(二进制)

HessianRPC设计思想

:::info 服务调用者: 客户端 SlefService HessianProxyFactory 做服务代理 工具 参数

  1. 接口 OrederService--->JDK Proxy.newProxyInstance(ClassLoader,OderService,InvovationHndler)
  2. url

服务的接口 做成公共模块 :::

HessianRPC 的开发

准备依赖

  <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>  

开发步骤

服务端(RPC远端功能提供者)

  • 开发服务 :::info
  1. 开发Service
  2. DAO----Mybaits

注意 一定要定义Service的接口,自定义的类型要实现序列化接口 :::

public interface UserService {
    boolean login(String name,String password);
    void register(String name,String password);
}

@Slf4j
public class UserServiceImpl implements UserService {
    @Override
    public boolean login(String name, String password) {
        log.debug("login,{},{}",name,password);
        return false;
    }

    @Override
    public void register(String name, String password) {
        log.debug("name:{},password:{}",name,password);

    }
}

  • 发布服务 :::info
  1. web.xml进行配置 :::
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
	version="4.0">

	<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.huy.service.UserService</param-value>
		</init-param>
		<init-param>
			<param-name>home-class</param-name>
			<param-value>com.huy.service.UserServiceImpl</param-value>
		</init-param>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>userServiceRPC</servlet-name>
		<url-pattern>/userServiceRPC</url-pattern>
	</servlet-mapping>
</web-app>


客户端(远端服务的调用者)

:::info HessianProxyFactory 参数: 远端服务的接口 url ::: image.png

@Slf4j
public class HessianRPCClient {
   public static void main(String[] args) throws MalformedURLException {
      HessianProxyFactory hessianProxyFactory=new HessianProxyFactory();
      String URL="http://localhost:8080/rpc-hessian/userServiceRPC";
      UserService userService = (UserService) hessianProxyFactory.create(UserService.class, URL);
      boolean userServiceRet = userService.login("xiaohei", "123456");
      log.debug("userServiceRet value is{}",userServiceRet);
   }
}

HessianRPC核心源码分析

:::info HessoanRPC 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()");
        } else {
            InvocationHandler handler = null;
            handler = new HessianProxy(url, this, api);
            return Proxy.newProxyInstance(loader, new Class[]{api, HessianRemoteObject.class}, handler);
        }
    }

:::info 代理中: 1. 通过网络Http请求,链接远端RPC服务 2. 通过流数据写出 HessianProxy#invoke()

  1. 通过URLConnection 进行网络链接
  2. 解析协议 传递数据
    :::

HessianRPC 序列化

:::info Hessian 的RPC 已经过时了 但Hessian序列化方式还在使用(Dubbo) :::

  • 开发
public class TestHessianSerializable {
   public static void main(String[] args) throws IOException {
      //Hessian序列化的目的 就是为了传输数据 基本类型 对象 Serializable 接口
/*      OutputStream outputStream=new FileOutputStream("test");
      Hessian2Output out=new Hessian2Output(outputStream);
      out.writeObject(new User("suns","1234"));
      out.flush();
      outputStream.close();*/
      //Hessian反序列化
      InputStream inputStream=new FileInputStream("test");
      Hessian2Input in=new Hessian2Input(inputStream);
      User user = (User) in.readObject(User.class);
      System.out.println(user);

   }
}