場景
Thrift介紹以及Java中使用Thrift實現RPC示例:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108689413
在上面講了在Java中使用Thrift實現遠程過程調用。實現了在客戶端調用服務端的方法。
但是這都是在Java項目中。
Thrift的強大之處並不止於此,如果想實現在兩個不同的語言的服務端可客戶端中實現RPC,
比如在Java客戶端中調用Python服務端的方法或者在Python客戶端中調用Java服務端的方法。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關注公眾號
霸道的程序猿
獲取編程相關電子書、教程推送與免費下載。
實現
前面在使用Thrift生成Java代碼時的thrift文件為
namespace java thrift.generated typedef i16 short typedef i32 int typedef i64 long typedef bool boolean typedef string String struct Person { 1:optional String username, 2:optional int age, 3:optional boolean married } exception DataException { 1:optional String message, 2:optional String callback, 3:optional String date } service PersonService { Person getPersonByUsername(1:required String username) throws (1:DataException dataException), void savePerson(1:required Person person) throws(1:DataException dataException) }
為了能生成代碼,添加一個py的namespace
namespace py py.thrift.generated
添加之后的完成代碼
namespace java thrift.generated namespace py py.thrift.generated typedef i16 short typedef i32 int typedef i64 long typedef bool boolean typedef string String struct Person { 1:optional String username, 2:optional int age, 3:optional boolean married } exception DataException { 1:optional String message, 2:optional String callback, 3:optional String date } service PersonService { Person getPersonByUsername(1:required String username) throws (1:DataException dataException), void savePerson(1:required Person person) throws(1:DataException dataException) }
之前已經將thrift的編譯器添加進環境變量,所以在IDEA中的Ternimal中使用其生成Python代碼
thrift --gen py src/thrift/MyData.thrift
后面跟的是thrift文件的位置
此時會在項目根目錄下生成gen-py目錄,里面就是生成的python代碼
新建Python項目PyThrift,這里使用PyCharm再打開Ternimal,使用pip安裝thrift
pip install thrift
然后將上面生成的python代碼的gen-py下面的py目錄和__init_.py復制到Pycharm中的Python項目中
Python客戶端請求Java服務端
在Python項目中新建py_client.py
# -*- coding:utf-8 -*- __author__='公眾號:霸道的程序猿' from py.thrift.generated import PersonService from py.thrift.generated import ttypes from thrift import Thrift from thrift.transport import TSocket from thrift. transport import TTransport from thrift. protocol import TCompactProtocol 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 = 50 newPerson.married = True client.savePerson(newPerson) transport.close() except Thrift.TException as tx: print(tx.message)
注意這里的Python客戶端所使用的通信層和傳輸層的協議要和上面博客中Java客戶端使用的一致。
然后運行Java中的服務端,以及Python中的客戶端
可以看到Python的客戶端調用了Java服務端的兩個方法成功。
Java客戶端調用Python服務端
在Python項目中新建PersonServiceImpl.py作用與之前Java服務端的實現類相同都是實現
thrift中struct中定義的接口方法。
# -*- coding:utf-8 -*- __author__='公眾號:霸道的程序猿' from py.thrift.generated import ttypes class PersonServiceImpl: def getPersonByUsername(self,username): print('Python 服務端獲取到客戶端傳來的參數:'+username) person = ttypes.Person() person.username = username person.age = 50 person.married = True return person def savePerson(self,person): print('Python 服務端獲取客戶端的參數:') print(person.username) print(person.age) print(person.married)
然后再新建服務端py_server.py
# -*- coding:utf-8 -*- __author__='公眾號:霸道的程序猿' from py.thrift.generated import PersonService from PersonServiceImpl import PersonServiceImpl from thrift import Thrift from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TCompactProtocol from thrift.server import TServer try: personServiceHandler = PersonServiceImpl() processor = PersonService.Processor(personServiceHandler) serverSocket = TSocket.TServerSocket(host='127.0.0.1',port=8899) transportFactory = TTransport.TFramedTransportFactory() protocolFactory = TCompactProtocol.TCompactProtocolFactory() server = TServer.TSimpleServer(processor,serverSocket,transportFactory,protocolFactory) server.serve() except Thrift.TException as ex: print(ex.message)
注意這里的TServerSocket中的參數不僅要有端口還要有port,並且這里的host如果設置localhost的話
會提示拒絕連接,所以這使用的是127.0.0.1
運行Python的服務端,然后再運行Java的客戶端
在Java客戶端中調用Python服務端的方法成功。
示例代碼下載
https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/12869384