Skip to content

Thrift中实现Java与Python的RPC互相调用

场景

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

 

 


深圳SEO优化公司玉林营销网站公司东营百度竞价公司开封网站制作设计公司阜新外贸网站设计报价盐田网络推广大庆企业网站改版公司石家庄seo网站优化公司和县SEO按天扣费推荐自贡网站排名优化公司惠州网络推广价格临沧网站关键词优化哪家好咸宁SEO按效果付费多少钱永州企业网站设计价格三亚网络广告推广邯郸模板推广哪家好红河网站搭建价格武威百度竞价包年推广多少钱荆州建设网站多少钱运城网站设计模板哪家好平顶山网页制作报价滨州网站优化排名多少钱咸阳如何制作网站推荐衢州网站制作多少钱丽水百搜标王推荐益阳关键词排名阳江企业网站制作邵阳网络营销哪家好广东建网站价格开封百度网站优化报价张家口网络广告推广歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化