使用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方法

 

posted @ 2020-10-09 13:47  tonglin0325  阅读(630)  评论(0编辑  收藏  举报