tonglin0325的个人主页

使用thrift的java client调用python server

参考:Thrift 连接 Java 与 Python,附 Java 通用工厂方法

上面这篇文章的例子是使用java client调用python server中的helloString方法来打印client传输过去的字符串

thrift文件,hello.thrift

1
2
3
4
service Hello {
string helloString(1:string word)
}

Server端

生成Python server端代码

1
2
thrift --gen py hello.thrift

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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代码

 

1
2
thrift --gen java hello.thrift

pom文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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主函数

1
2
3
4
5
6
7
8
9
10
11
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方法