一. 远程通讯协议的基本原理
网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基于 Socket 概念上为某类应用场景而扩展出的传输协议,网络 IO ,主要有 bio 、 nio 、 aio 三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。
二. 应用级协议 Binary-RPC
Binary-RPC 是一种和 RMI 类似的远程调用的协议,它和 RMI 的不同之处在于它以标准的二进制格式来定义请求的信息 ( 请求的对象、方法、参数等 ) ,这样的好处是什么呢,就是在跨语言通讯的时候也可以使用。
来看下 Binary -RPC 协议的一次远程通信过程:
1 、客户端发起请求,按照 Binary -RPC 协议将请求信息进行填充;
2 、填充完毕后将二进制格式文件转化为流,通过传输协议进行传输;
3 、接收到在接收到流后转换为二进制格式文件,按照 Binary -RPC 协议获取请求的信息并进行处理;
4 、处理完毕后将结果按照 Binary -RPC 协议写入二进制格式文件中并返回。
问题总结:
1 、传输的标准格式是?
标准格式的二进制文件。
2 、怎么样将请求转化为传输的流?
将二进制格式文件转化为流。
3 、怎么接收和处理流?
通过监听的端口获取到请求的流,转化为二进制文件,根据协议获取请求的信息,进行处理并将结果写入 XML 中返回。
4 、传输协议是?
Http 。
三. Hessian ——一种实现远程通讯的 library
Hessian 是由 caucho 提供的一个基于 binary-RPC 实现的远程通讯 library 。
1 、是基于什么协议实现的?
基于 Binary-RPC 协议实现。
2 、怎么发起请求?
需通过 Hessian 本身提供的 API 来发起请求。
3 、怎么将请求转化为符合协议的格式的?
Hessian 通过其自定义的串行化机制将请求信息进行序列化,产生二进制流。
4 、使用什么传输协议传输?
Hessian 基于 Http 协议进行传输。
5 、响应端基于什么机制来接收请求?
响应端根据 Hessian 提供的 API 来接收请求。
6 、怎么将流还原为传输格式的?
Hessian 根据其私有的串行化机制来将请求信息进行反序列化,传递给使用者时已是相应的请求信息对象了。
7 、处理完毕后怎么回应?
处理完毕后直接返回, hessian 将结果对象进行序列化,传输至调用端。
Hessian机制
那么Hessian就是把Java对象转变成 字节序列,然后通过Http传输到 目标服务器上(主机2),主机2收到这个字节序列后,按照一定的协议标准进行反序列,提交给对应的服务处理。处理完成以后以同样的方式返回数据。
现在我们回头看看例子中的配置(WEB-INF.XML):
配置的Servlet: com.caucho.hessian.server.HessianServlet
对应的参数:接口(home-api):com.alisoft.enet.hessian.Hello
实现(home-class): com.alisoft.enet.hessian.HelloImpl
HessianServlet 中的实现代码如下(略过部分代码):
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
InputStream is = request.getInputStream();
OutputStream os = response.getOutputStream();
//输入流
Hessian2Input in = new Hessian2Input(is);
SerializerFactory serializerFactory = getSerializerFactory();
in.setSerializerFactory(serializerFactory);
//输出流
AbstractHessianOutput out;
int major = in.read();
int minor = in.read();
out = new Hessian2Output(os);
out.setSerializerFactory(serializerFactory);
_homeSkeleton.invoke(in, out);
整个执行步骤如下:
l 接收输入流,并通过SerializerFactory转化为 Hessian 特有的 Hessian2Input
l 设置输出流,并通过SerializerFactory转化为 Hessian 特有的 Hessian2Output
l 根据配置的接口和实现参数,调用服务,并把结果写入到输出流 Hessian2Output中
l Out.close()
Hessian远程访问基于序列化和反序列化的方式。当程序运行时,程序所创建的各种对象都位于内存中,当程序运行结束,这些对象就结束了生命周期。对象的序列化主要有两种用途:
l 把对象的字节序列永久地保存到硬盘上,通常是放在一个文件中。
l 在网络上传输对象的字节序列
四. Hessian 源码分析
以 hessian 和 spring dm server 整合环境为例。
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;
2. 服务器端接收请求并处理请求
服务器端截获相应请求交给:
org.springframework.remoting.caucho.HessianServiceExporter
具体处理步骤如下:
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);
总结: 由上面源码分析可知,客户端发起请求和服务器端接收处理请求都是通过 hessian 自己的 API 。输入输出流都要封装为 hessian 自己的 Hessian2Input 和 Hessian2Output ,接下来一节我们将去了解 hessian 自己封装的输入输出到底做了些什么!
五. Hessian 的序列化和反序列化实现
hessian 源码中 com.caucho.hessian.io 这个包是 hessian 实现序列化与反序列化的核心包。其中AbstractSerializerFactory , AbstractHessianOutput , AbstractSerializer , AbstractHessianInput ,AbstractDeserializer 是 hessian 实现序列化和反序列化的核心结构代码。
1. AbstractSerializerFactory ,它有 2 个抽象方法:
根据类来决定用哪种序列化工具类
abstract public Serializer getSerializer(Class cl) throws HessianProtocolException;
根据类来决定用哪种反序列化工具类
abstract public Deserializer getDeserializer(Class cl) throws HessianProtocolException;
2. SerializerFactory 继承 AbstractSerializerFactory 。
在 SerializerFactory 有很多静态 map 用来存放类与序列化和反序列化工具类的映射,这样如果已经用过的序列化工具就可以直接拿出来用,不必再重新实例化工具类。
在 SerializerFactory 中,实现了抽象类的 getSerializer 方法,根据不同的需要被序列化的类来获得不同的序列化工具,一共有 17 种序列化工具, hessian 为不同的类型的 java 对象实现了不同的序列化工具,默认的序列化工具是 JavaSerializer 。
在 SerializerFactory 中,也实现了抽象类的 getDeserializer 方法,根据不同的需要被反序列化的类来获得不同的反序列化工具,默认的反序列化工具类是 JavaDeserializer 。
3. HessianOutput 继承 AbstractHessianOutput 成为序列化输出流的一种实现。
它会实现很多方法,用来做流输出。
需要注意的是方法,它会先调用 serializerFactory 根据类来获得 serializer 序列化工具类
public void writeObject(Object object)
throws IOException
{
if (object == null) {
writeNull();
return;
}
Serializer serializer;
serializer = _serializerFactory.getSerializer(object.getClass());
serializer.writeObject(object, this);
}
4. 现在我们来看看 AbstractSerializer 。
其 writeObject 是必须在子类实现的方法, AbstractSerializer 有 17 种子类实现, hessian 根据不同的java 对象类型来实现了不同的序列化工具类,其中默认的是 JavaSerializer 。
而 JavaSerializer 的 writeObject 方法的实现,遍历 java 对象的数据成员,根据数据成员的类型来获得各自的 FieldSerializer ,一共有 6 中默认的 FieldSerializer 。
拿默认的 FieldSerializer 举例,还是调用 AbstractHessianOutput 的子类来 writeObject ,这个时候,肯定能找到相应的 Serializer 来做序列化
同理可以反推出 hessian 的反序列化机制。 SerializerFactory 可以根据需要被反序列化的类来获得反序列化工具类来做反序列化操作。
总结:得益于 hessian 序列号和反序列化的实现机制, hessian 序列化的速度很快,而且序列化后的字节数也较其他技术少。
精彩科技工作室
相关推荐
它提供了高效的远程调用能力,相比基于文本的协议(如SOAP),Hessian能更节省带宽和提高通信效率。Hessian库可以在不同平台上使用,支持多种编程语言,简化了跨语言的远程服务调用。 WebService是一种基于XML的、...
1. **Hessian简介**:Hessian是由Caucho Technology开发的一种二进制Web服务协议,它提供了简洁、快速的数据传输方式,尤其适用于低带宽环境。Hessian支持RPC模式,允许服务端和客户端之间进行方法调用。 2. **Java...
一、Hessian简介 Hessian是由Caucho公司开发的一种轻量级的Web服务协议,它的主要特点是使用二进制格式传输数据,相比XML或JSON,其在网络传输中具有更高的效率和更快的速度。Hessian支持Java、C++、Python等多种...
一、Hessian简介 Hessian是由Caucho公司开发的一种轻量级的二进制Remoting协议,它提供了高效的序列化和反序列化机制,使得跨平台的远程方法调用(RMI)变得更加便捷。Hessian支持HTTP传输,可以在防火墙开放的HTTP...
一、Hessian简介 Hessian是一种基于HTTP的二进制协议,它以简洁的二进制格式传输数据,相比于XML-RPC或JSON-RPC等文本协议,Hessian具有更高的传输效率和更快的解析速度。Hessian支持Java、C++、Python等多种语言,...
#### 一、Hessian简介 Hessian是一个轻量级的远程服务调用框架,其核心功能是提供类似于RMI(远程方法调用)的服务,但采用的是更为高效的二进制RPC(远程过程调用协议)。这使得Hessian非常适合用于传输大量的二...
#### 一、Hessian简介 Hessian是一个轻量级的远程服务调用框架,其主要特点在于采用高效的二进制格式进行数据传输,这使得它非常适合处理大量的二进制数据。Hessian通过HTTP协议进行通信,并且支持多种编程语言。它...
**一、Hessian简介** Hessian是由Caucho Technology公司开发的一种二进制RPC(Remote Procedure Call)协议,它能够将Java对象序列化为高效的二进制格式,从而显著减少网络传输的数据量。Hessian支持HTTP协议,可以...
一、Hessian简介 Hessian是由Caucho公司开发的一种基于HTTP的二进制RPC(Remote Procedure Call)协议,它以简洁的二进制格式传输数据,从而提高了网络通信效率。Hessian协议支持Java、.NET、Python等多种语言,使得...
一、Hessian协议简介 Hessian协议基于HTTP协议,但其数据传输采用二进制格式,这使得它在数据传输效率上远超基于文本的XML或JSON协议。Hessian支持多种类型的数据序列化,包括基本类型、对象、数组、日期等,并且...
二、Hessian简介 Hessian是由Caucho公司开发的一种二进制RPC协议,它通过HTTP协议传输,具有序列化速度快、传输数据量小的特点。Hessian支持Java、C++、Python等多种语言,使得不同平台和语言之间的通信变得简单。 ...
#### 一、Hessian简介 Hessian是一种轻量级的远程过程调用(RPC)协议,相比传统的WebService技术,Hessian提供了更简单且高效的方式来实现分布式应用间的通信。Hessian的核心优势在于其采用了二进制RPC协议(Binary ...
一、简介 Hessian是基于Binary-RPC协议实现的远程通讯library,用于实现远程过程调用(RPC)。Hessian提供了一个轻量级的RPC解决方案,支持多种编程语言,并且具有高性能和可扩展性。 二、Hessian的工作原理 ...
#### 二、Hessian矩阵简介 **定义**:Hessian矩阵是多元函数二次导数的矩阵表示形式。对于一个具有两个变量\( x_1 \)和\( x_2 \)的函数\( f(x_1, x_2) \),其Hessian矩阵\( H(f) \)定义为: \[ H(f) = \begin{b...
### Hessian协议简介 Hessian协议是基于HTTP的,它通过二进制编码来提高数据传输效率,相比于XML或JSON等文本格式,Hessian在数据量和传输速度上有显著优势。Hessian协议支持基本类型(如整型、浮点型、字符串等)...
一、Frangi-Hessian算法简介 Frangi-Hessian算法是Frangi在1998年提出的一种针对血管检测的特征提取方法。该算法的核心在于利用Hessian矩阵,它是图像二阶导数的表示,可以捕捉图像中的局部特征。Hessian矩阵H的...
一、Hessian协议简介 Hessian是一种轻量级的序列化和通信协议,它的主要特点是: 1. **二进制格式**:Hessian使用二进制格式传输数据,相比XML或JSON等文本格式,占用带宽更少,传输速度更快。 2. **自动类型检测**...
一、Spring 4与Hessian 4简介 Spring 4是Spring框架的一个版本,它提供了一整套企业级应用开发的支持,包括依赖注入、AOP(面向切面编程)、数据访问、事务管理等。Hessian 4则是一种二进制Web服务协议,它能高效地...
1. **反序列化简介**: - 序列化是指将对象的状态信息转换为可以存储或传输的形式的过程;而反序列化则是指将序列化的数据恢复为对象的过程。 - 在 Java 中,可以利用 `java.io.Serializable` 接口实现对象的序列...
- **简介**:Hessian是一种二进制的Web服务协议,由Caucho公司开发。Hessian-lite是Hessian的轻量级实现,专为Java设计,用于减少网络传输的数据量,提高服务调用效率。 - **功能**:Hessian-lite使得远程调用更加...