笔者,不玩游戏已经有一个月的时间了。昨天偶然发现大家都在玩吃鸡,于是好奇心作祟,昨个不知不觉就到了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百度百科》