使用thrift快速开发接口工具

最近看了看thrift接口工具,感觉还是不错的。可以用来快速的开发基于Socket的接口工具。简单的说,就是可以让人快速的写Socket Server和Client。其实不用thrift开发socket也不难,那么为什么要用thrift开发呢?主要有两个原因,一个是因为thrift本身帮你封装了很多基本的东西,你不需要自己去写socket里面的bind,accept之类的,以及他们的逻辑。可以很快速的开发基于进程的,线程的,SSL的socket。第二个理由是标准化,跨语言和跨平台,windows不算在其中。主要是在各种Posix兼容的操作系统中都可以不需要改造基本直接可用,支持的语言种类也很多,基本你会写的,他都支持。你不会写的,他也支持。

类似的项目还有ICE和Avro,但是感觉都没有thrift做的易用性好。而且这是facebook开源的诸多项目中,为数不多的能正常编译的软件。

当前thrift版本是0.8.0
支持的语言如下

ActionScript3
glibc
cocoa(开发ios用的)
C++
C#
delphi
erlang
go
haskell
html
java
javame(山寨机开发)
jquery
node.js
Ocaml
perl
php
python
ruby
smalltalk
xsd

安装是很简单的Linux三板斧,就不说了。

使用thrift需要先定义接口文件,在thrift里简称叫IDL,全称叫Interface Description Language,接口描述语言。接口描述语言里面需要定义接口中所使用的数据类型,方法等等。

数据类型包括

基本类型:
bool: 布尔类型(true或者false)
byte: 有符号8位整型
i16: 有符号16位整型
i32: 有符号32位整型
i64: 有符号64位整型
double: 64位浮点数
string: UTF8编码的字符串

特殊类型:
binary: 未编码的二进制字节流
struct:结构体类型

container:
list:列表,可以理解为数组,其中的元素可以是任意类型的。

exceptions:
用来抛出你自己定义的异常情况

service:
这个是我觉得最重要的定义,有些地方说是虚函数,我觉得理解成你程序中所使用的方法更容易明白一些。他需要你定义返回类型,这有点类似于C或者java的函数定义。但你要明白,这个返回是给socket的。如果你定义错了,将不仅仅是你得不到返回值这么简单的事情。而是程序会报错

我们来尝试写第一个thrift文件

test.thrift
service test
{
        string GetSysVer()
        #一个获取系统版本的方法,返回给socket一个字符串

        string FileTransfer(1:string filename, 2:binary content )
        #传送文件的方法,入口参数为string类型的文件名和二进制流类型的文件内容,方法将给socket一个字符串类型的返回值,如果你需要传送结构体,可以在Service外面定义struct File{1:string filename,2:binary content,3:i64:filelen...}等等,然后用list类型赋值给入口参数,例如string FileTransfer(1:list<File> transfer)

        bool FileExists(1:string filename)
        #检查server端指定文件是否存在,返回布尔
}

假设我们用Python来写接口:
thrift --gen py test.thrift

server端文件

host = '0.0.0.0'
#监听地址
port = 12345
#监听端口

import sys
import os
import platform

sys.path.append('./gen-py')
from test import *
from test.ttypes import *

# Thrift files
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

class testHandler:
                def FileTransfer(self, filename, content):
                                filename = filename
                                content = content
                                f = open(filename,"wb")
                                f.write(content)
                                f.close()
                                return "1"

                def FileExists(self, filename):
                                if os.path.isfile(filename):
                                                return True
                                else:
                                                return False

                def GetSysVer(self):
                                system_ver = platform.platform()
                                if system_ver.find("el5") > 0:
                                                title = '5'
                                elif system_ver.find("el6") > 0:
                                                title = '6'
                                else:
                                                title = 'Not CentOS'
                                return title

handler = testHandler()
processor = test.Processor(handler)
transport = TSocket.TServerSocket(host,port)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
print 'Starting server'
server.serve()

这样server端就写完了,来看下client

host = '127.0.0.1'
port = 12345

import sys
import platform

sys.path.append('./gen-py')

from test import *
from test.ttypes import *

# Thrift files
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

try:

                # Init thrift connection and protocol handlers
                transport = TSocket.TSocket(host , port)
                transport = TTransport.TBufferedTransport(transport)
                protocol = TBinaryProtocol.TBinaryProtocol(transport)

                agent = test.Client(protocol)
                transport.open()

                res = agent.FileExists("/root/test.thrift")
                if res == True:
                             print "True"
                else:
                             print "False"

                filename = "/tmp/Aptana_Studio_3_Setup_Linux_x86_64_3.0.9.zip"
                #定义服务端文件名和保存路径
                f = open("./Aptana_Studio_3_Setup_Linux_x86_64_3.0.9.zip","rb")
                #本地文件路径
                content = f.read()
                f.close()

                boolean = agent.FileTransfer(filename,content)

                res = agent.GetSysVer()
                print res

                transport.close()
except Thrift.TException, tx:
                print 'Something went wrong : %s' % (tx.message)

整个Server和Client就写完了,服务器端的代码TThreadedServer是多线程的服务器,可以换成TThreadPoolServer基于线程池的,TSimpleServer是单线程的,TForkingServer基于新启进程的等等根据需要变换。

当然不仅仅是用python,用什么语言取决于你生成什么样的文件,更取决于你的项目需求。主要的好处就是标准化和跨语言做的很好。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
thrift-generator 是通过 Java接口生成 thrift 文件的工具。例子:public interface ICommonUserService {     public User login(int id, String name);     public User getUserById(long id);     public boolean saveUser(User user);     public List getUserIds(long id);      public Map getUserByIds(List ids);     public Map<String, List> getUsersByName(List names);     public Map<Long, List> getGroupUsers(List names, List userList, List lns, long ll);     public List testCase1(Map num1, List num2, List num3, long num4, String num5); } public class ThriftStructBuilderTest {     private ThriftFileBuilder fileBuilder = new ThriftFileBuilder();     @Test     public void toOutputstream() throws Exception {         this.fileBuilder.buildToOutputStream(ICommonUserService.class, System.out);     } }执行代码:mvn test -Dtest=com.sohu.thrift.generator.builder.ThriftStructBuilderTest之后控制台输出如下:namespace java com.sohu.thrift.generator.test.thrift     enum Status {             NORMAL = 0,             BLOCKED = 1     }     struct Account {             1:i32 id,             2:string name     }     struct User {             1:i32 id,             2:string name,             3:bool sex,             4:Status status,             5:list ids,             6:Account account     }     service ICommonUserService {             User login(1:i32 arg0,2:string arg1),             map<string, list> getUsersByName(1:list arg0),             bool saveUser(1:User arg0),             map getUserByIds(1:list arg0),             list getUserIds(1:i64 arg0),             map<i64, list> getGroupUsers(1:list arg0,2:list arg1,3:list arg2,4:i64 arg3),             User getUserById(1:i64 arg0),             list testCase1(1:map arg0,2:list arg1,3:list arg2,4:i64 arg3,5:string arg4)     }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值