Hessian原理分析

一种实现远程通讯的 library

1.远程通讯协议的基本原理

网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基于 Socket 概念上为某类应用场景而扩展出的传输协议,网络 IO ,主要有 bio 、 nio 、 aio 三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。

2.应用级协议 Binary-RPC

Binary-RPC 是一种和 RMI 类似的远程调用的协议,它和 RMI 的不同之处在于它以标准的二进制格式来定义请求的信息 ( 请求的对象、方法、参数等 ) ,这样的好处是什么呢,就是在跨语言通讯的时候也可以使用。

来看下 Binary -RPC 协议的一次远程通信过程:

  1. 客户端发起请求,按照 Binary -RPC 协议将请求信息进行填充
  2. 填充完毕后将二进制格式文件转化为流,通过传输协议进行传输
  3. 接收到在接收到流后转换为二进制格式文件,按照 Binary -RPC 协议获取请求的信息并进行处理
  4. 处理完毕后将结果按照 Binary -RPC 协议写入二进制格式文件中并返回

3.例子

3.1 客户端发起请求

Hessian 的这个远程过程调用,完全使用动态代理来实现的。有客户端可以看出。

除去 spring 对其的封装,客户端主要是通过 HessianProxyFactory 的 create 方法就是创建接口的代理类,该类实现了接口, JDK 的 proxy 类会自动用 InvocationHandler 的实现类(该类在 Hessian 中表现为 HessianProxy )的 invoke 方法体来填充所生成代理类的方法体。

客户端系统启动时:

     根据 serviceUrl 和 serviceInterface 创建代理。

     HessianProxyFactoryBean 类

HessianClientInterceptor 类

createHessianProxy(HessianProxyFactory proxyFactory)

HessianProxyFactory 类

public Object create(Class api, String urlName)

客户端调用 hessian 服务时:

HessianProxy 类的 invoke(Object proxy, Method method, Object []args) 方法

String methodName = method.getName();// 取得方法名

    Object value = args[0]; // 取得传入参数
    conn = sendRequest(mangleName, args) ;      // 通过该方法和服务器端取得连接
    httpConn = (HttpURLConnection) conn;
    code = httpConn.getResponseCode();    // 发出请求

// 等待服务器端返回相应…………

    is = conn.getInputStream();
   Object value = in.readObject(method.getReturnType()); // 取得返回值

HessianProxy 类的 URLConnection sendRequest(String methodName, Object []args) 方法:

URLConnection  conn = _factory.openConnection(_url);      // 创建 URLConnection 
OutputStream os = conn.getOutputStream();
AbstractHessianOutput out = _factory.getHessianOutput(os); // 封装为 hessian 自己的输入输出 API
out.call(methodName, args)
return conn;
3.2 服务器端接收请求并处理请求

将输入输出封转化为转化为 Hessian 特有的 Hessian2Input 和 Hessian2Output。

a) HessianServiceExporter 类

(HessianExporter) invoke(request.getInputStream(), response.getOutputStream());

b) HessianExporter 类

(Hessian2SkeletonInvoker) this.skeletonInvoker.invoke(inputStream, outputStream);

c) Hessian2SkeletonInvoker 类

将输入输出封转化为转化为 Hessian 特有的 Hessian2Input 和 Hessian2Output

  Hessian2Input in = new Hessian2Input(isToUse);
  in.setSerializerFactory(this.serializerFactory);
  AbstractHessianOutput out = null;
  int major = in.read();
  int minor = in.read();
  out = new Hessian2Output(osToUse);
  out = new HessianOutput(osToUse);
  out.setSerializerFactory(this.serializerFactory);
  (HessianSkeleton) this.skeleton.invoke(in, out);

d) HessianSkeleton 类
读取方法名

String methodName = in.readMethod();
Method method = getMethod(methodName);
读取方法参数
Class []args = method.getParameterTypes();
Object []values = new Object[args.length];
执行相应方法并取得结果
 result = method.invoke(service, values);
 结果写入到输出流
 out.writeObject(result);
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值