本案例使用Java
与Python
两种语言进行互相调用测试Thrift
IDL文件(.thrift文件) #定义命名空间: namespace 语言名 路径 namespace java thrift.generatednamespace py py.thrift.generated#定义类型别名 typedef i16 shorttypedef i32 inttypedef i64 longtypedef bool booleantypedef string String#定义一个消息/对象/结构体 关键字struct struct Person { 1 :optional String username, 2 :optional int age, 3 :optional boolean married } #定义一个异常,数据传递时/方法调用是可能出现的异常 关键字exception #服务端如果出现异常的话直接抛给客户端,让客户端catch 处理 exception DataException { 1 :optional String message; 2 :optional String callStack; 3 :optional String date; } #定义服务接口 关键字service #定义一系列方法,就是客户端于服务端进行交互所调用的方法,具体实现由服务端完成 service PersonService { Person getPersonByUsername(1 :required String username) throws (1 :DataException dataException), void savePersion(1 :required Person person) throws (1 :DataException dataException) }
使用thrift编译器生成编译文件 生成Java代码
thrift --gen java src/thrift/data.thrift
生成Python代码
thrift --gen py src/thrift/data.thrift
Java所有实现 引入依赖 使用包管理器使用Gradle
org.apache.thrift:libthrift:0.13.0
编写接口实现类 实际开发中放在服务端
public class PersonServiceImpl implements PersonService .Iface { @Override public Person getPersonByUsername (String username) throws DataException, TException { System.out.println("Got Client Param:" + username); Person person = new Person().setUsername(username) .setAge(18 ).setMarried(false ); return person; } @Override public void savePersion (Person person) throws DataException, TException { System.out.println("Got Client Param:" ); System.out.println(person.getUsername()); System.out.println(person.getAge()); System.out.println(person.isMarried()); } }
服务器端 public class ThriftServer { public static void main (String[] args) throws Exception { TNonblockingServerSocket socket = new TNonblockingServerSocket(8899 ); THsHaServer.Args arg = new THsHaServer.Args(socket) .minWorkerThreads(2 ).maxWorkerThreads(4 ); PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl()); arg.protocolFactory(new TCompactProtocol.Factory()); arg.transportFactory(new TFramedTransport.Factory()); arg.processorFactory(new TProcessorFactory(processor)); TServer server = new THsHaServer(arg); System.out.println("Thrift Server Started!" ); server.serve(); } }
客户端 public class ThriftClient { public static void main (String[] args) { TTransport transport = new TFramedTransport( new TSocket("localhost" ,8899 ),600 ); TProtocol protocol = new TCompactProtocol(transport); PersonService.Client client = new PersonService.Client(protocol); try { transport.open(); Person person = client.getPersonByUsername("星空" ); System.out.println(person.getUsername()); System.out.println(person.getAge()); System.out.println(person.isMarried()); System.out.println("------------------" ); Person person1 = new Person().setUsername("测试" ) .setAge(18 ).setMarried(false ); client.savePersion(person1); }catch (Exception e){ throw new RuntimeException(e.getMessage(),e); }finally { transport.close(); } } }
Python所有实现 本项目的Python代码基于Python2
pip安装 Archlinux安装pip
sudo pacman -S python-pip
python-pip包会吧当前系统存在的python版本对应的pip都装上
使用pip或pip2安装thrift源码
如果是python专用软件则会自动被扫描到thrift,如果使用vscode指定pip安装的文件目录,会更容易识别
例如:
"python.autoComplete.extraPaths": [ "/home/sakura/.local/lib/python2.7/site-packages/" //这里填自己的 ],
查看pip安装包安装路经 如果不知道pip安装的位置可以运行python2/python3,然后import要查看路径的包,再输入包的名称,即可查看安装路径了
❯ python2 Python 2.7.18 (default, Apr 23 2020, 22:32:06) [GCC 9.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import thrift >>> thrift <module 'thrift' from '/home/sakura/.local/lib/python2.7/site-packages/thrift/__init__.pyc'>
编写接口实现类 from py.thrift.generated import *class PersonServiceImpl : def getPersonByUsername (self,username) : print "Python Got client param:" + username person = ttypes.Person() person.username = username person.age = 18 person.married = False return person def savePersion (self,person) : print "Python Got client param:" print person.username print person.age print person.married
服务端 from py.thrift.generated import PersonServicefrom PersonServiceImpl import PersonServiceImplfrom thrift import Thriftfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TCompactProtocolfrom thrift.server import TServerimport sysreload(sys) sys.setdefaultencoding('utf-8' ) try : personServiceHandler = PersonServiceImpl() processor = PersonService.Processor(personServiceHandler) serverSocket = TSocket.TServerSocket(port=8899 ) transportFactory = TTransport.TFramedTransportFactory() protocolFactory = TCompactProtocol.TCompactProtocolFactory() server = TServer.TSimpleServer(processor,serverSocket,transportFactory,protocolFactory) server.serve() except Thrift.TException, ex: print '%s' % ex.message
客户端 from thrift import Thriftfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TCompactProtocolimport sysreload(sys) sys.setdefaultencoding('utf-8' ) from py.thrift.generated import *try : tSocket = TSocket.TSocket('localhost' ,8899 ) tSocket.setTimeout(600 ) transport = TTransport.TFramedTransport(tSocket) protocol = TCompactProtocol.TCompactProtocol(transport) client = PersonService.Client(protocol) transport.open() person = client.getPersonByUsername("三木" ) print person.username print person.age print person.married print "------------" newPerson = ttypes.Person() newPerson.username = "星空" newPerson.age = 18 newPerson.married = True client.savePersion(newPerson) transport.close() except Thrift.TException, tx: print '%s' % tx.message
测试 Python作为服务端,Java作为客户端 服务端打印:
Python Got client param:星空 Python Got client param: 测试 18 False
客户端打印:
星空 18 false ------------------