使用thrift的java client調用python server

參考:Thrift 連接 Java 與 Python,附 Java 通用工廠方法

上面這篇文章的例子是使用java client調用python server中的helloString方法來打印client傳輸過去的字符串

thrift文件,hello.thrift

service Hello {
    string helloString(1:string word)
}

Server端

生成Python server端代碼

thrift --gen py hello.thrift

 python server端代碼,其中包括生成的hello文件夾中的代碼,以及server代碼

from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from thrift.transport import TSocket
from thrift.transport import TTransport

from hello import Hello


class HelloHandler:
    def __init__(self):
        pass

    def helloString(self, word):
        ret = "hello Thrift! Received: " + word
        return ret


# handler processer類
handler = HelloHandler()
processor = Hello.Processor(handler)
transport = TSocket.TServerSocket("127.0.0.1", 8989)
# 傳輸方式,使用buffer
tfactory = TTransport.TBufferedTransportFactory()
# 傳輸的數據類型:二進制
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
# 創建一個thrift 服務~
server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
print("Starting thrift server in python...")
server.serve()
print("done!")

 

Client端

生成java client代碼

 

thrift --gen java hello.thrift

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>thrift-example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.10.0</version>
        </dependency>
    </dependencies>

</project>

java client的代碼

package com.example.tutorial;

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 org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ThriftFactory {

    private ThriftFactory() {
    }

    private static final Logger LOG = LoggerFactory.getLogger(ThriftFactory.class);
    private static TProtocol protocol;
    private static TTransport transport;

    /**
     * 獲取二進制 protocol
     *
     * @return 二進制 protocol
     */
    public static TProtocol getTProtocol() {
        // 單例獲取 protocol
        if (protocol == null) {
            protocol = new TBinaryProtocol(getTTransport());
        }
        return protocol;
    }

    /**
     * 獲取傳輸對象
     *
     * @return 傳輸對象
     */
    public static TTransport getTTransport() {
        // 單例獲取 transport
        if (transport == null) {
            // 應改成從配置文件讀取
            String ip = "127.0.0.1";
            Integer port = 8989;
            transport = new TSocket(ip, port);
        }
        return transport;
    }

    /**
     * 獲取客戶端實例
     *
     * @param clazz 客戶端類
     * @param <T>   泛型
     * @return 客戶端實例
     */
    public static <T> T getClient(Class<T> clazz) {
        T instance = null;
        try {
            //獲取有參構造器
            Constructor c = clazz.getConstructor(TProtocol.class);
            // 實例化客戶端,需要傳入 protocol
            instance = (T) c.newInstance(getTProtocol());
        } catch (Exception e) {
            LOG.error("", e);
            throw new RuntimeException(e.getMessage());
        }
        return instance;
    }

    /**
     * 發起請求
     *
     * @param clazz      客戶端類
     * @param methodName 方法名,客戶端中不能有重載的方法
     * @param param      方法參數
     * @param <T>        泛型
     * @return 方法返回值
     */
    public static <T> Object doRequest(Class<T> clazz, String methodName, Object... param) {
        Object result = null;
        try {
            // 獲取客戶端實例
            T instance = getClient(clazz);
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                // 獲取指定的方法
                if (method.getName().equals(methodName)) {
                    open();
                    result = method.invoke(instance, param);
                    close();
                    break;
                }
            }
        } catch (Exception e) {
            LOG.error("", e);
            throw new RuntimeException(e.getMessage());
        }
        return result;
    }

    /**
     * 打開傳輸
     */
    public static void open() {
        try {
            getTTransport().open();
        } catch (TTransportException e) {
            LOG.error("", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 關閉傳輸
     */
    public static void close() {
        getTTransport().close();
    }

}

client主函數

package com.example.tutorial;

public class ThriftExample {

    public static void main(String[] args) {
        String msg = (String) ThriftFactory.doRequest(com.example.tutorial.Hello.Client.class, "helloString", "測試");
        System.out.println(msg);
    }

}

運行python server

運行java client,調用了python的helloString方法

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章