浅析利用Hessian跨Web网站发送数据包
更新:HHH   时间:2023-1-7


笔者,不玩游戏已经有一个月的时间了。昨天偶然发现大家都在玩吃鸡,于是好奇心作祟,昨个不知不觉就到了5点多。笔者现在的电脑配置是10年前的,现在最大的期待是能够有一台配置高、外观漂亮的电脑。好了,每天闲扯一下其实很开心,也主要是现在的游戏大都是3D体验感的,笔者晕3D渲染(配置低的电脑更明显),没办法啊。好了废话不多说了,现在我们实现一种跨Web网站的数据推送技术:从当前的Web网站生成一个数据文件包,然后将该数据文件包推送到另一个Web网站中,实现网站展现效果的实时推送。对此,笔者尝试使用Hessian解决跨Web服务进行服务器间的数据推送。
总结一下hessian:
1、 相比WebService,Hessian更简单、快捷。
2、采用的是二进制RPC协议
RPC是指远程过程调用协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。
3、对象必须进行序列化
由于使用二进制RPC协议传输数据,对象必须进行序列化,实现Serializable 接口
4、通过 Hessian 本身提供的 API 来发起请求。
5 、Hessian 通过其自定义的串行化机制将请求信息进行序列化,产生二进制流。
6、Hessian 基于 Http 协议进行传输。
7、响应端根据 Hessian 提供的 API 来接收请求。
8、Hessian 根据其私有的串行化机制来将请求信息进行反序列化,传递给使用者时已是相应的请求信息对象了。
9 、处理完毕后直接返回, hessian 将结果对象进行序列化,传输至调用端。
调用端通过 HessianProxyFactory 的 create 方法就是创建接口的代理类,该类实现了接口, JDK 的 proxy 类会自动用 InvocationHandler 的实现类(该类在 Hessian 中表现为 HessianProxy )的 invoke 方法体来填充所生成代理类的方法体。
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;
被调用端接收请求并处理请求
被调用端截获相应请求交给:
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,跨Web服务的数据推送。
参考资料《Hessian百度百科》

返回开发技术教程...