浏览模式: 标准 | 列表
12月
31

PHPRPC 3.0.1 for Delphi 发布

这是今年发布的 PHPRPC 的最后一个版本更新,也是 PHPRPC 3.0 协议实现的最后更新。从明年将开始 PHPRPC 3.1 协议的制定与实现,3.0 版本的协议实现因为已经稳定,所以不再进行更新。

本次更新的主要内容有:

  • 移除了 PHPUtils.pas。
  • 将原来 PHPUtils.pas 中的所有内容移动到 PHPRPC.pas 中。
  • 将 TPHPObject 的基类从 TObject 改为 TComponent。
  • 修改了 TPHPObject 的反序列化方法,将被反序列化的对象设为其所有属性及其属性相关对象的拥有者,这样,当该对象被释放时,所有与该对象属性相关的对象也会一同被释放。
  • 对 THashMap 的反序列化方法做了同样的修改。
  • 消除了在 Delphi 2009 上编译时的所有警告。
  • 使 Delphi 2009 跟 Delphi 6-2007 都可以以同样的方式工作。
  • 修改了 ByteArrayToString 和 StringToByteArray 方法,使其可以在不需要转换时仍然可以正常工作。
  • 修改了对字节数组的序列化和反序列化方式,使其按照原始字节字符串方式进行序列化和反序列化。
  • 为 TPHPRPC_Client 增加了 StringAsByteArray 属性,当该属性设置为 true 时,则原始字节字符串将按照字节数组进行反序列化。
  • 为 PHPRPC_Client 组件增加了图标。

» 阅读全文

12月
31

2009年的 PHPRPC 开发计划

  • 升级协议到3.1版,增加更多可以提高效率的特性(如立即清除服务器端密钥的请求等),并完全兼容现有版本。
  • 提供更多常用编程语言的实现(如 C/C++、D、Erlang 等)。
  • 为PHPRPC协议提供TCP、UDP绑定版本,并实现与现有 HTTP 绑定版本的无差别编程接口,可以让企业内部的分布式软件构建更加简单高效。

» 阅读全文

12月
31

2008年终总结

转眼又是一年,今年经历不少,大体上总结一下:

工作经历:

  • 年初辞掉了学校的工作,回家过了最后一个寒假,不过已经无薪了,哈哈。
  • 3月去北京,在体坛网工作了近三个月,几乎天天加班,还没有加班费,所谓的调休也只是一句空话,连已经请下来的婚假公司都可以反悔,还可以以此来作为借口降薪,所以我只能说这是一个无德的公司。
  • 6月回家跟bawbaw开始第一次创业计划,但被alan所骗,到10月还没有拿到钱。幸得bawbaw相助,才度过难关。算是又放了一个暑假,只不过这个暑假有点长,还是无薪的,呵呵。
  • 10月中旬加入到现在的公司,之后工作的一直都很顺利啦,很喜欢现在的公司和现在的工作,没有加班,正常的休假,还有一帮热情的同事,感谢bawbaw介绍我加入这个大家庭。

生活经历:

  • 3月在北京老婆怀孕。
  • 4月办准生证费了不少劲,因此要特别感谢万恶的计划生育执行部门。
  • 五一长假回家办婚礼,结婚都2年了才照婚纱照和办婚礼,可见以前有多忙了。
  • 6月回家常住。
  • 11月23日19时38分,我儿子mario(马立傲)降生,我升级成mario之父。
  • 之后就是整天被mario忙的团团转啦,一直转到现在,哈哈。

PHPRPC开发经历:

  • 今年是PHPRPC发展最快的一年,相继实现了.NET、ActionScript、J2ME、Delphi、Ruby、Python 等版本,支持的语言增加到了十多种。并且所有的版本在稳定性、效率、支持范围上都有了前所未有的突破。
  • PHPRPC技术交流用户群也从最初的寥寥几人,到现在爆满不得不转移到500人的新群,特别要感谢小鱼鱼提供了新群。
  • PHPRPC有了真正的像样的网站,虽然页面不多,但总算看上去向那么回事了,呵呵。不过文档还需要完善。

» 阅读全文

下面是对在 .NET Framework 3.5 中对 PHP、Binary、SOAP、XML、JSON、Hessian 和 Burlap 序列化/反序列化的效率对比,其中 PHP 序列化来自最新版本的 PHPRPC 3.0.1 for .NET,Hessian 和 Burlap 序列化来自Hessian C# 的最新版 1.3.3,其它的序列化都是采用 .NET Framework 3.5 中内置的功能。

测试程序可从此处下载:test.zip

下面是测试程序的运行结果图:

大小: 30 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 30.4 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 30.33 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 29.72 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 31.22 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 29.51 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 34.28 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 34.41 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 36.12 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 39.11 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 35.34 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图

大小: 34.93 K
尺寸: 500 x 292
浏览: 0 次
点击打开新窗口浏览全图
 

从上面的运行结果来看 PHP 序列化和反序列化:

对于基本类型的效率跟 Hessian 不相上下,远远超过其它序列化方式,甚至比 .NET 的 Binary 序列化和反序列化都要快好几倍。但是 Burlap 不支持浮点数的无穷大表示。

对于字节数组来说,速度是 Binary 序列化的 2 倍,是 Hessian 的 10 倍,是 Burlap 的 25 倍,是 SOAP 的 36 倍,是 JSON 的 1000 多倍!

对于数组来说,具有相同元素的数组,比 Binary 序列化要差一些,但是远远超过 SOAP、XML、JSON、Hessian 和 Burlap。具有不同元素的数组,跟 Binary、Hessian 序列化效率接近,比 XML、JSON、Burlap 稍快,远远超过 SOAP。

对于 Hashtable 来说,效率也是超过 .NET Binary、Hessian 和 Burlap 序列化。比 SOAP 快近 10 倍,比 JSON 快了近 100 倍!而 XML 不支持。

对于 ArrayList 和自定义类型来说,效率不如 .NET Binary 序列化,但是仍然远远超过 SOAP、Hessian 和 Burlap,而 XML 和 JSON 则根本不支持。

而在空间占用上,其效率也超过了 Binary、SOAP、XML、Burlap,在基本类型上与 JSON、Hessian 不相上下,对于数组、Hashtable 则远远超过 JSON。

所以,从上面的对比来看,PHPRPC 中所使用的 PHP 序列化是一种非常高效的数据表示方式,远远超过 SOAP、XML、JSON、Burlap 等序列化方式。其效率跟 .NET Binary、Hessian 序列化的效率可以算是不相上下,在综合水平上甚至超越了 .NET Binary、Hessian 序列化。另外在跨语言跨平台方面,PHPRPC 所使用的 PHP 序列化方式则比 .NET Binary 序列化要好的多,而 PHPRPC 本身又在稳定性、易用性、安全性、功能性和脚本语言的支持上又比 Hessian 好很多,通过这些数据我想更加可以说明 PHPRPC 的优秀了。

» 阅读全文

本文是针对 PHPRPC for Delphi 原生程序开发版本的介绍,如果您使用的是 .NET 版本可以忽略本文。

PHPRPC for Delphi 是以组件形式提供的,目前只提供了客户端组件,它是非可视化的组件,所以不论是在窗口程序还是控制台程序中你都可以使用它。

直接在 Delphi 中安装该组件包后就可以使用了,不过目前只提供了 Delphi 7 和 Delphi 2009 的组件安装包。如果你是用其它版本的 Delphi 可以通过自己创建组件包来安装,或者将现有版本的组件包转换为你所使用版本的组件包。

安装组件包非常简单。如果你是用的是 Delphi 7,打开 PHPRPC_D7.dpk 编译安装即可。如果你使用的是 Delphi 2009,打开 PHPRPC_D2009.dproj 编译安装即可。按照之后就可以直接从 Internet 面板上找到 PHPRPC_Client 组件了。

为了方便讲解,这里给出的演示是控制台程序:

Delphi/Pascal代码
  1. program Example;    
  2.     
  3. {$APPTYPE CONSOLE}    
  4.     
  5. uses    
  6.   PHPRPC;    
  7.     
  8. var    
  9.   client: TPHPRPC_Client;    
  10.   clientProxy: Variant;    
  11.   intArray: array of Integer;    
  12.   arraylist: TArrayList;    
  13.   vhashmap: Variant;    
  14.   ohashmap: THashMap;    
  15.   i: Integer;    
  16. begin    
  17.   // 创建客户端对象,如果是图形界面程序,直接拖放组件到 Form 即可。  
  18.   client := TPHPRPC_Client.Create;    
  19.   // 返回远程代理对象,通过它就可以直接调用远程方法了。  
  20.   // 因为实际上该代理对象是 client 对象的 Variant 包装,所以该代理对象不需要单独释放。    
  21.   clientProxy := client.useService('http://localhost/index.aspx');  
  22.   
  23.   // 设置交换密钥的长度(可选,默认 128)  
  24.   client.KeyLength := 256;  
  25.   // 设置加密模式(0 - 不加密、1 - 单向加密、2 - 双向加密、3 - 双向且输出加密),默认为 0  
  26.   client.EncryptMode := 1;  
  27.     
  28.   // 数字参数    
  29.   writeln(clientProxy.add(12));    
  30.     
  31.   // 英文字符串参数    
  32.   writeln(clientProxy.add('foo''bar'));    
  33.     
  34.   // Delphi 7 中文字符串参数要转换为UTF8编码    
  35.   writeln(UTF8ToAnsi(clientProxy.Hello(AnsiToUTF8('马秉尧'))));    
  36.     
  37.   // Delphi 2009 中文字符串参数默认为UnicodeString    
  38.   // writeln(UTF8ToAnsi(clientProxy.Hello('马秉尧')));    
  39.     
  40.   // 中文的服务器输出的也是UTF8编码,本地打印要转换为本地编码    
  41.   writeln(UTF8ToAnsi(client.Output));    
  42.     
  43.   // 传递动态数组参数    
  44.   setLength(intArray, 10);    
  45.   // 主要不要越界    
  46.   for i := 0 to 9 do intArray[i] := Random(100000);    
  47.   // 返回值是 Variant 包装的 THashMap    
  48.   vhashmap := clientProxy.sort(Variant(intArray));    
  49.   // 这里不能用索引方式访问    
  50.   for i := 0 to 9 do writeln(vhashmap.get(i));    
  51.   writeln;    
  52.   // 使用完之后释放掉, 以免造成内存泄漏    
  53.   // 但动态数组不需要显式释放,它会在程序运行结束后自动释放    
  54.   vhashmap.Free;    
  55.     
  56.   // 传递数组列表参数    
  57.   // 注意这里初始化了10个元素的空间,但是实际用了11个元素    
  58.   // 因为数组列表有自增长的特性,因此不会发生越界访问的情况    
  59.   // 但上面的动态数组则不可以越界访问,否则会发生意想不到的错误    
  60.   arraylist := TArrayList.Create(10);    
  61.   for i := 0 to 10 do arraylist[i] := Random(100000);    
  62.     
  63.   vhashmap := clientProxy.sort(arraylist.ToVariant);    
  64.   // 这里不能用索引方式访问    
  65.   for i := 0 to 10 do writeln(vhashmap.get(i));    
  66.   writeln;    
  67.     
  68.   // 可以显式通过 FromVariant 方法转换成 THashMap 对象    
  69.   ohashmap := THashMap(THashMap.FromVariant(vhashmap));    
  70.   // 这里不能用get方法访问    
  71.   for i := 0 to 10 do writeln(ohashmap[i]);    
  72.   writeln;    
  73.     
  74.   // 释放掉原来的未排序数组    
  75.   arraylist.Free;    
  76.     
  77.   // 将返回结果转换为 TArrayList 类型    
  78.   arraylist := ohashmap.ToArrayList;    
  79.   for i := 0 to 10 do writeln(arraylist[i]);    
  80.   writeln;    
  81.     
  82.   vhashmap.Free;    
  83.   // vhashmap 释放后 ohashmap 也一起释放,反之亦然    
  84.   // 因此下面注释掉的语句如果执行的话会出错(或让程序崩溃)    
  85.   // for i := 0 to 10 do writeln(ohashmap[i]);    
  86.     
  87.   // 但通过 ToArrayList 转换得到的是新对象,所以仍然可以使用    
  88.   for i := 0 to 10 do writeln(arraylist[i]);    
  89.     
  90.   // 因此不要忘记释放资源,以免造成内存泄漏    
  91.   arraylist.Free;    
  92.   client.Free;    
  93.   readln;  
  94. end.    

因为 Delphi 2009 中引入了 UnicodeString,所以不需要 AnsiToUTF8 就可以正确按照 UTF-8 编码来传输 string 了。上面的程序中关于中文字符串部分已经给出了在不同版本下的解决方案,但是 Delphi 7 的写法在 Delphi 2009 上也可以继续使用。不过目前的 PHP 4/5 还不支持 Delphi 中传输的 WideString 字符串,但将来的 PHP 6 会支持。目前其它所有语言的 PHPRPC 服务器都已经支持 Delphi 中传输的 WideString 字符串。

其它需要注意的问题都已经在注释中写清楚了,这里就不再重复了。

» 阅读全文