python java thrift,thrift服务(for Python/Java)的简易搭建步骤(不求甚解版)

关于这个话题,网上有大量的文章;但是配置部分都讲得比较混乱,直接拷来并不能跑通。

本文以python和java分别作为服务端/客户端及其逆形式进行了演示,不求甚解,只求能用。

定义好thrift文件,作为C/S的契约

xxx.thrift

注意:以下代码都是手动混淆过的,仅大致示意写法,不保证内容正确

namespace java com.x1.x2.x3.x4.x5.gen_java # 注意,如果是为java版本准备的,一定要写好package

struct MyStruct1{

1:string field1,

2:list field2,

3:optional list field3, # 注意java不支持optinal,生成的代码中只有必选项

}

struct MyStruct2{

1:list data

}

service MyService{

void f1(1:MyStruct1 s1)

list f2(1:string field1, 2:MyStruct1 data)

}

将thrift文件分别编译成服务器端语言和客户端语言

注意:自动生成的python代码中,可能有class A依赖class B,而A的代码却写到了同一个文件中B的下方的情况;这可能是thrift的一个BUG,手动调整代码顺序即可

mkdir gen_py gen_java # 默认名字是用短横线分隔(gen-py),不符合python的包命名要求;手动改成下划线

thrift -r --gen py -out gen_py xxx.thrift

thrift -r --gen java -out ../../../../../../ xxx.thrift # 路径中有x1-x5,就要上6层

实现服务端逻辑

注意:

gen_py和gen_java文件夹的内容最好别改动;它们都只是作为辅助类库使用的

服务器端要自己写一个Handler类去override指定的方法

客户端只要绑定到指定的端口上调用即可

python版服务器端

先用自己的类来继承IFace,实现各个接口

# thrift 相关的引用

from thrift.protocol import TBinaryProtocol

from thrift.server import TServer

from thrift.transport import TSocket, TTransport

# import ... # 逻辑相关的引用

class MyHandler(MyService.Iface):

def __init__(self):

transport = TSocket.TSocket('hostname', 8095) # 最好用IP,稳一点

transport = TTransport.TBufferedTransport(transport)

transport.open() # 注意这一行不能少

protocol = TBinaryProtocol.TBinaryProtocol(transport)

# self.xxx = yyy 之类的初始化,省略 ...

def f1(self, arg1):

pass # ...

然后写一个server.py来包裹handler并控制服务的起停

from thrift.protocol import TBinaryProtocol

from thrift.server import TServer

from thrift.transport import TSocket, TTransport

# sys.path.append('thrift/gen_py') # 可能需要把gen_py加到PYTHONPATH

# import ... # 逻辑相关的引用

def main():

handler = MyHandler()

processor = MyService.Processor(handler)

transport = TSocket.TServerSocket('10.1.x.x', 8081)

tfactory = TTransport.TBufferedTransportFactory()

pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)

logger.info('---------- starting xxx server over thrift...')

server.serve()

logger.info('---------- shutting down xxx server over thrift...')

if __name__ == '__main__':

main()

java版的服务器端

同理,先写个Handler类来覆盖相应的method

package com.xxx.xxx.xxx

// import ...

public class MyHandler implements MyService.Iface {

@Override

public synchronized void f1(MyStruct1 arg1) throws TException {

// ...

}

// ...

}

然后写个Server类来包裹Handler并控制服务的起停

package com.x.x.x.xxx

import ... // 逻辑相关的引用

import org.apache.thrift.server.TServer;

import org.apache.thrift.server.TSimpleServer;

import org.apache.thrift.server.TThreadPoolServer;

import org.apache.thrift.transport.TServerSocket;

import org.apache.thrift.transport.TTransportException;

import java.io.IOException;

import java.net.InetSocketAddress;

public class MyServer {

public static void main(String[] args) throws IOException, TTransportException {

MyService.Processor processor = new MyService.Processor(new MyHandler());

TServerSocket serverTransport = new TServerSocket(new InetSocketAddress("1.2.3.4", 1234));

TServer server = new TSimpleServer(new TThreadPoolServer.Args(serverTransport).processor(processor));

System.out.println("Starting server...");

server.serve();

}

}

实现客户端逻辑

java版客户端

先把之前运行thrift -r --gen java ...命令生成的gen_java文件夹拷进来,作为一个package;

然后把Guava等其它各种类库写进maven/Gradle。

插一句:如果用到读写wav文件的功能,可以把wavFile相关的类库

package com.xxx.yyy;

import org.apache.thrift.TException;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.protocol.TProtocol;

import org.apache.thrift.transport.TSocket;

import org.apache.thrift.transport.TTransport;

// import ...

public class App {

public void work(List arg) {

try {

TTransport transport = new TSocket("1.2.3.4", 1234); // 注意两边都尽量用IP,比较稳一点

transport.open();

TProtocol protocol = new TBinaryProtocol(transport);

MyService.Client client = new MyService.Client(protocol);

// arg1 = ...

client.f1(arg);

// 多次调用 client.f2(...)

transport.close();

System.out.println("----- client done");

} catch (TException ex) {

ex.printStackTrace();

} // 更多catch ...

}

public static void main(String[] args) {

App app = new App();

app.work(Lists.newArrayList("arm", "aunt", "autumn"));

}

}

python版的客户端写法

from thrift.protocol import TBinaryProtocol

from thrift.transport import TSocket, TTransport

# 可能需要将gen_py加到PYTHONPATH

# import 逻辑相关的模块 ...

def main():

transport = TSocket.TSocket('1.2.3.4', 8081)

transport = TTransport.TBufferedTransport(transport)

transport.open()

protocol = TBinaryProtocol.TBinaryProtocol(transport)

client = MyService.Client(protocol)

# arg = ...

client.f1(arg)

# 多次调用 client.f2(...)

print('----- client done')

if __name__ == '__main__':

main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值