读书人

PHPRPC 让 SOA 从梦想成为现实

发布时间: 2012-11-04 10:42:42 作者: rapoo

PHPRPC 让 SOA 从梦想变成现实
SOA 是一种程序设计思想,其实早在远古时代(计算机史)它就已经出现了。无非就是把系统分解,将数据和业务逻辑部分尽量独立出来,然后以服务形式提供给另外的系统共用。

那时也有一些可以实现 SOA 的工具,比如 DCOM、CORBA 等,不过前者仅限于 Windows,后者又太复杂,而且也仅对 C/C++、Delphi、Java 这等语言有较好支持,而且也都是商业开发软件中才会包含,对于开源的脚本类语言来说支持很差甚至没有支持(因为太复杂了,不是什么人都可以实现的了的,能够把整个 CORBA 规范完整读下来,都需要很好的耐心,还不一定都能够完全理解)。之后互联网发展了,XML-RPC 出现了,XML-RPC 很简单,但是也太过简单(因为它只是一个 SOAP 的实验原型而已),简单的数据可以传输,复杂点的就没办法了,所以后来就发展成了 SOAP 这个名字简单实际却很复杂的怪物,尽管 SOAP 已经够复杂了,但它也不过仅仅是定义了数据格式,于是后来就又有了一堆 WS-* 的补充。这样就变得跟 CORBA 一样了,不再是什么人都能理解,什么人都能实现了,或者说除了大公司和大组织有这个能力外,其他人基本上没有这个能力介入。再之后人们突然想发现了宝一样,发现了几年前就被提出来的 REST,于是一堆号称 REST 的服务又出现了,这东西看上去简单,可是实际上却是把数据转换、传输等等问题全都扔给使用者来自行解决了。最后 REST 教父都把这些号称 REST 的服务给否定了。除了这些以外,当然还有其它的方案,比如 Hessian、ICE、Adobe 的基于 AMF3 的通信方案等等,这些不能不说是好的技术,但不是局限于某几种语言,就是局限于某个特定的应用范围。所以要搞 SOA 就需要在这些不同的协议和解决方案之间进行转换,这就出来了 ESB,到这里之后已经看上去很好很强大了。可是它真的可以解决问题吗?真的不是在制造新问题吗?当然它解决了一定的问题,可是同样也制造了更多新问题。能够在各种技术之间转换固然很好,可是本来要掌握这些很复杂的技术中的一种就已经是一件很困难的事了,还要几种都学,几种都要用,这是多大的挑战啊!还有一个问题就是这些协议中本来就有慢的要命的(比如基于 SOAP 的 Web Service),还要再加个转换的过程,那还有什么效率可言。所以,ESB 最后就变成了“哦,傻逼”!SOA 也就变成了听上去很美,做起来很难的东西。

可是实际上我们回过头来再想想,我们要 SOA 到底是想实现什么?不就是要将系统分解,然后异构重组吗?最后问题就这么简单,我们需要的不一定是基于 SOAP 的 Web Service,不一定是将各种协议都能进行转换的 ESB。我们需要的是一种能够在异构系统间可以有效的进行数据交换的技术,这样我们就已经可以构建 SOA 的系统了。别的技术我不敢说,至少目前 PHPRPC 做到了这一点,你不但可以在 Java、.NET 这些语言之间方便的交换数据,还可以跟 PHP、Ruby、Python、Perl 这些开源脚本语言中以同样的方式交换数据,还可以用 Delphi/BCB 来做 Windows 界面的前台,也可以用 JavaScript 做 Web 前台,还可以用 Flash/Flex/RIA/WPF/SilverLight 这些来做内容更丰富的前台,而所有这些前台都可以共享同一个后台,还不需要关心后台究竟用什么语言来实现。甚至手机上的 J2ME、.NET CF、Flash Lite 和手机浏览器的 JavaScript 都可以完美支持。有了 PHPRPC 之后,你就突然就有了这么多选择,甚至随着 PHPRPC 的发展,你还会有更多更多的选择,SOA 从现在开始就不再是遥不可及的梦了。List<String> list = new ArrayList<String>();list.add("dfsfsdf");list.add("ggwertewr");list.add("1234ggwertewr");user.setList(list);phprpc_server.add("getList", user);

当在客户端取数据时,
List list = user.getList();
数据的确在list内,可通过list.size()知道list的大小,但在访问list内字符串数据时,总是报java.lang.ClassCastException: [B.........
请问一下这是什么原因呢?
我个人认为,应该是客户端根本就不知道服务端返回的list的数据是什么类型(就算知道list服务端传过来的是String List,强行转型也会出错),应该是直接以字节数组的形式传过来的,
那么我要获取list的字符串,是不是要挨过的将每一个字节数组转换成字符串哟,如果真是这样,那传一个自定义对象list
岂不是非常的麻烦。

您的判断非常的正确,确实字符串是以 byte[] 形式返回的,在不能明确获知字符串类型的情况下,字符串和字符数组都是以字节数组的形式表示的。

Java 的泛型只是一个语法糖,所以它的泛型元素类型是无法通过反射来获取的(这点与 .NET 泛型完全不同),因此,Java 的泛型元素类型如果设置为基本类型(包括String)和容器类型的话,则无法正确接收,只有自定义类型对象才可以用泛型容器来接受,因为自定义类型对象在序列化时是包含准确的类型信息的。

不过向这种类型,你可以在客户端通过声明成 String[] 来接收,因为这样就可以获取到元素类型,并自动进行正确的转换。否则,你就只能用非泛型接口(如List)或非泛型类(如ArrayList)接收了,接收之后,对于元素需要用 org.phprpc.util.Cast.cast 方法来进行类型转换。

测试时我也遇到这个情况,作者能解决吗?不然转换很麻烦

这个问题产生的原因是PHPRPC所用的序列化格式不能区分二进制字符串和Unicode字符串,所以这个在PHPRPC里是硬伤,没办法修改。不过好消息是,我们的商业开源版软件Hprose中,这个硬伤被解决啦,而且是彻底的解决,所有类型都不需要做类型转化了(甚至连org.phprpc.util.Cast这样的帮助类都不存在了,因为完全不需要了)。Hprose在性能上还有大幅提升,效率是PHPRPC的10几倍,在易用性上也有了更大的改善,如果您有兴趣的话,可以测试一下。

读书人网 >PHP

热点推荐