因为最近要用到RPC,考察了一下thrift(facebook用的一套rpc框架)和google protocol buffer。

thrift支持的语言非常多,不光支持c++,java,python,ruby等非常流行的语言外还支持ocaml,Squeak等很少见的语言,比google protocol buffer好多了,而且已经内置RPC,不像google protocol buffer的RPC还藏着掖着。比较google protocol buffer和thrift的文章比较多,其中google到的比较靠前的一篇blog指出thift的c++版本对windows支持不好,我一开始也是觉得如此,主要是thrift只提供了autoconf,automake作为构建工具,在windows上只能用cygwin或者msys才能比较方便的编译,而google protocol buffer提供了vc的工程文件。另外在代码的规范性方面,的确是google protocol buffer更好。

此次移植的目的是在windows上运行的client和compiler,因为server肯定是用linux的,移植没太大必要。根据我从前移植代码的经验,发现妨碍移植的关键在于系统api的差异,或者是某些依赖库的差异,如果差异太大,则移植比较麻烦。另外,在移植时我比较倾向于先移植一个最小的功能集合,并逐步完善。

在泛读了thrift的代码和文档后发现thrift中并没有用到非常难于移植的api,我先用thrift compiler开始,thrift compiler很简单,基本不用修改就可以在vc2008上编译,主要依赖的是flex和bison,在windows下也都不难找到,也可以在linux生成后,再把生成的thriftl.cc,thrifty.cc和thrifty.h直接copy过来使用。编译完成后发现在处理include和externs的时候有问题,主要是linux和windows的路径分隔符("/"和"\\")的差异,修改main.cc里面的program_name和directory_name就可以解决了,这个问题在msys下面也存在。

接下来就是client和server了,我打算主要使用Framed Transport+Binary protocol+nonblocking server,因为使用的是libevent(在windows上已经有移植,直接拿过来用就可以了,在linux上面用的是epoll,性能也不错),也没有其他的依赖库,移植起来还是比较方便的。

先从client开始,在TSocket中因为使用了poll来进行超时处理,先改成阻塞方式,将所有的非阻塞和poll相关代码注释掉,基本可以编译成功,然后还有就是ctime_t的地方可以用vc的ctime_s代替,但是dbgtime的长度要改成26。运行tutorial没什么问题。然后就是加入超时处理了,虽然ms在windows server 2008里面引入了WSAPoll,我用的是xp,只有用select来模拟一个poll了,反正功能差不多,只是接口不太一样。完成后就可以生成基本的client runtime库了。

至于server,大致看了一下,里面主要的问题是使用了socketpair和poll,主要是用来做libevent的通知。不过socketpair就自己建两个socket然后连接起来就可以了,poll用之前client的select模拟实现,移植起来问题应该不大。

client的代码因为移植时间比较紧,只有半天时间,还没清理,就不放上来丢人了。

只发一个tutorial的client的exe(需要vc9的runtime才能运行),修改后的Framed Transport+Binary protocol+nonblocking server的linux server代码和compiler的vc9工程代码。下载