一. 前言
本次主要采用thrift進(jìn)行多語(yǔ)言的調(diào)用,使用python作為服務(wù)實(shí)現(xiàn)即服務(wù)端,c++和java作為客戶(hù)端來(lái)對(duì)python程序進(jìn)行跨語(yǔ)言調(diào)用。
二. 開(kāi)發(fā)環(huán)境
Windows10
jdk11
python3.8
VS2019C++
thrift0.14.1
三. 具體過(guò)程
1.環(huán)境配置thrift下載安裝
進(jìn)入http://www.apache.org/dyn/closer.cgi?path=/thrift/0.14.1/thrift-0.14.1.exe下載thrift
添加環(huán)境變量
cmd調(diào)用
2.java調(diào)用python代碼
編寫(xiě)MyData.thrift文件說(shuō)明接口情況
namespace java thrift.generated
namespace py py.thrift.generated
namespace cpp cpp.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)
boolean getImageService() throws(1:DataException dataException)
}
使用命令生成相關(guān)接口文件
thrift --gen py src/thrift/MyData.thrift
拷貝py文件夾及init文件到新建的python項(xiàng)目中
編寫(xiě)實(shí)現(xiàn)類(lèi)ServiceImpl
from py.thrift.generated import ttypes
import cv2
import matplotlib.pyplot as plt
class ServiceImpl:
def getImageService(self):
print("received picture change message")
img = cv2.imread('flower.jpg')
rows, cols = img.shape[:2]
# 第一個(gè)參數(shù)旋轉(zhuǎn)中心,第二個(gè)參數(shù)旋轉(zhuǎn)角度,第三個(gè)參數(shù):縮放比例
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)
# 第三個(gè)參數(shù):變換后的圖像大小
res = cv2.warpAffine(img, M, (rows, cols))
cv2.imwrite("result.jpg", res)
return True
def getPersonByUsername(self, username):
print('Python 服務(wù)端獲取到客戶(hù)端傳來(lái)的參數(shù):' + username)
person = ttypes.Person()
person.username = username
person.age = 50
person.married = True
return person
def savePerson(self, person):
print('Python 服務(wù)端獲取客戶(hù)端的參數(shù):')
print(person.username)
print(person.age)
print(person.married)
主函數(shù)實(shí)現(xiàn)
from py.thrift.generated import PersonService
from ServiceImpl import ServiceImpl
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 = ServiceImpl()
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)
java端同樣生成所需要的并復(fù)制過(guò)去
編寫(xiě)java客戶(hù)端:
package com;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.apache.thrift.transport.layered.TFramedTransport;
public class ThriftClient {
public static void main(String[] args) throws TTransportException {
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("jwy");
System.out.println(person.getUsername());
System.out.println(person.getAge());
System.out.println(person.isMarried());
System.out.println("------------------------");
Person person1 = new Person();
person1.setUsername("jwy");
person1.setAge(50);
person1.setMarried(true);
client.savePerson(person1);
Boolean isok=client.getImageService();
System.out.println("圖像變換調(diào)用:"+isok);
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage(), ex);
} finally {
transport.close();
}
}
}
啟動(dòng)客戶(hù)端服務(wù)端結(jié)果:
3.c++調(diào)用python代碼
使用VS2019安裝vcpkg及thrift
首先安裝VS英語(yǔ)語(yǔ)言庫(kù)
否則會(huì)報(bào)
Warning: The following VS instances are excluded because the English language pack is unavailable.
D:\Visual Studio 2019
Please install the English language pack.
No suitable Visual Studio instances were found
的錯(cuò)誤
vcpkg安裝請(qǐng)參考https://docs.microsoft.com/en-us/cpp/build/install-vcpkg?view=msvc-160&tabs=windows
安裝vcpkg完成后,進(jìn)入相關(guān)目錄,輸入命令
vcpkg install thrift:x64-windows
安裝thrift完成
這次換個(gè)thrift文件hello.thrift
namespace cpp cpp.thrift.generated
namespace py py.thrift.generated
service HelloService
{
void hello(1: string name);
}
同樣使用命令
thrift --gen py src/thrift/hello.thrift
thrift --gen cpp src/thrift/hello.thrift
拷貝到對(duì)應(yīng)目錄
編寫(xiě)client.cpp
#include "HelloService.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TCompactProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using namespace ::cpp::thrift::generated;
using namespace std;
int main(int argc, char** argv)
{
shared_ptr<TTransport> socket(new TSocket("127.0.0.1", 8899));
shared_ptr<TTransport> transport(new TFramedTransport(socket));
shared_ptr<TProtocol> protocol(new TCompactProtocol(transport));
HelloServiceClient client(protocol);
try
{
transport->open();
client.hello("cpper.info");
transport->close();
}
catch (TException& tx)
{
printf("ERROR:%s\n", tx.what());
}
return 0;
}
開(kāi)啟服務(wù)端客戶(hù)端:
四. 總結(jié)與討論
此次實(shí)驗(yàn)主要困難在配置thrift環(huán)境,需要注意很多細(xì)節(jié)的東西,以及網(wǎng)絡(luò)問(wèn)題
特別是VS2019配置thrift需要下載cmake,vcpkg等工具,需要耐心配置。