Direct Link
Direct Link
本Demo用于展示 Thrift 跨平台(Linux,Windows)、跨编程语言(Python,Javascript,C++)的远过程调用(传输消息)功能,实现从某一应用程序(client)向另一应用程序(server)发送消息的过程。
ping() – 原文返回Client端送来的文本,在前面添加文本“echo:”
post() – 接收client送来的一个JSON字符串,并添加 “res”:True 字段/数值作为回应,否则,当收到非法JSON串,返回包含 “res”:False 字段/数值 的JSON串。
已完成测试:
Windows : Python, Javascript
Linux: Python, C++
Windows | Linux | |||
---|---|---|---|---|
Server | Client | Server | Client | |
Python | √ | √ | √ | √ |
JScript | √ | |||
C++ | √ |
sudo apt-get install automake bison flex g++ git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config
wget https://dlcdn.apache.org/thrift/0.15.0/thrift-0.15.0.tar.gz tar -xf thrift-0.15.0.tar.gz
./configure
配置运行结果:
thrift 0.16.0 Building C (GLib) Library .... : no Building C++ Library ......... : yes Building Common Lisp Library.. : no Building D Library ........... : no Building Dart Library ........ : no Building .NET Standard Library : no Building Erlang Library ...... : no Building Go Library .......... : no Building Haxe Library ........ : no Building Java Library ........ : no Building Lua Library ......... : no Building NodeJS Library ...... : no Building Perl Library ........ : no Building PHP Library ......... : no Building Python Library ...... : yes Building Py3 Library ......... : yes Building Ruby Library ........ : no Building Rust Library ........ : no Building Swift Library ....... : no C++ Library: C++ compiler .............. : g++ -std=c++11 Build TZlibTransport ...... : yes Build TNonblockingServer .. : yes Build TQTcpServer (Qt5) ... : no C++ compiler version ...... : g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 Python Library: Using Python .............. : /usr/bin/python Using Python version ...... : Python 3.8.10 Using Python3 ............. : /usr/bin/python Using Python3 version ..... : Python 3.8.10 If something is missing that you think should be present, please skim the output of configure to find the missing component. Details are present in config.log.
确认支持 C++, Python
sudo make sudo make install thrift -version
显示以下信息表示安装成功:
Thrift version 0.16.0
修改/etc/ld.so.conf文件,增加搜索路径,将/usr/local/lib添加到ld.so.conf文件中(指定库文件 *.so 的路径,否则运行应用程序时会出现缺少库文件错误)
sudo ldconfig
基本数据类型 数据类型简单明了,包含了所有编程语言中的可用基本数据类型。
bool:布尔值(true/false) byte:8位有符号整型 i16:16位有符号整型 i32:32位有符号整型 i64:64位有符号整型 double:64位浮点数 string:由utf8编码的文本字符串
特殊类型 binary:未编码的字节流
结构体(struct)
容器(container)
枚举
服务
命名空间
注释
A RPC description file below defining the RPC service interfaces.
service DemoService { string ping(1:string param) string post(1:string param) }
pip install thrift
# Interface for Python,generated code at ./gen-py thrift --gen py DemoService.thrift
from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.server import TServer import sys sys.path.append("./gen-py/") from DemoService import DemoService import json class DemoServer: def __init__(self): self.log = {} def ping(self, param): return "echo:" + param def post(self, jstr): try: jdict = json.loads(jstr) except Exception as e : return json.dumps({"res":False}) jdict["res"] = True return json.dumps(jdict); if __name__ == '__main__': handler = DemoServer() processor = DemoService.Processor(handler) # 监听端口 transport = TSocket.TServerSocket(host="0.0.0.0", port=9999) # 选择传输层 tfactory = TTransport.TBufferedTransportFactory() # 选择传输协议 pfactory = TBinaryProtocol.TBinaryProtocolFactory() # 创建服务端 server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) # 设置连接线程池数量 server.setNumThreads(5) # 启动服务 server.serve()
from thrift import Thrift from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol import sys sys.path.append("./gen-py/") from DemoService import DemoService import json if __name__ == '__main__': transport = TSocket.TSocket('127.0.0.1', 9999) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) client = DemoService.Client(protocol) # 连接服务端 transport.open() recv = client.ping("test") print(recv) recv = client.post(json.dumps({"Request":"Play"}) ) print(recv) # 断连服务端 transport.close()
运行服务端:
# Run service python service.py
运行Client端:
# Run client python client.py
运行结果:
echo:test {"Request": "Play", "res": true}
npm install thrift
# Interface for Node.js, generated code at ./gen-node.js thrift --gen js:node DemoService.thrift
var thrift = require('thrift'); var DemoService = require('./gen-nodejs/DemoService.js'); var transport = thrift.TBufferdTransport; var protocol = thrift.TBinaryProtocol; var connection = thrift.createConnection('localhost', 9999,{ transport : transport, protocol : protocol }); client = thrift.createClient(DemoService, connection); connection.on('error', function(err) { console.error(err); }); client.ping('From Node.js') .then(log); var json = { "Source": "node.js", "Request": "None" } client.post( JSON.stringify(json)) .then(log) function log(msg) { console.log(msg); }
运行client:
node client.js
运行结果:
echo:From Node.js {"Source": "node.js", "Request": "None", "res": true}
# Interface for C++,generated code at ./gen-cpp thrift -r --gen cpp DemoService.thrift
#include <iostream> #include "gen-cpp/DemoService.h" #include <transport/TSocket.h> #include <transport/TBufferTransports.h> #include <protocol/TBinaryProtocol.h> using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace std; #define REMOTE_ADDRESS "192.168.109.1" #define REMOTE_PORT 9999 int main(int argc, char **argv) { string res; ::std::shared_ptr<TSocket> socket(new TSocket(REMOTE_ADDRESS, REMOTE_PORT)); ::std::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); ::std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); DemoServiceClient client(protocol); transport->open(); client.ping(res, "From C++ Client"); cout << res << '\n'; client.post(res, "{\"Source\":\"C++\"}"); cout << res << '\n'; transport->close(); return 0; } // g++ -g -I/usr/local/include/thrift gen-cpp/DemoService.cpp client.cpp -lthrift -L/usr/local/lib/*.so -o client
编译:
g++ -g -I/usr/local/include/thrift gen-cpp/DemoService.cpp client.cpp -lthrift -L/usr/local/lib/*.so -o client
运行client:
./client
运行结果:
echo:From C++ Client {"Source": "C++", "res": true}
#include <iostream> #include "gen-cpp/DemoService.h" #include <server/TSimpleServer.h> #include <transport/TServerSocket.h> #include <transport/TBufferTransports.h> #include <protocol/TBinaryProtocol.h> using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using namespace apache::thrift::server; using boost::shared_ptr; using namespace std; #define REMOTE_ADDRESS "192.168.109.1" #define REMOTE_PORT 9999 class ServiceHandler : virtual public ServiceIf { public: ServiceHandler() { } void ping(std::string& _return, const std::string& param) { cout << param << '\n'; } void post(std::string& _return, const std::string& param) { cout << param << '\n'; } }; int main(int argc, char **argv) { int port = 9090; stdcxx::shared_ptr<ServiceHandler> handler(new ServiceHandler()); stdcxx::shared_ptr<TProcessor> processor(new ServiceProcessor(handler)); stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); stdcxx::shared_ptr<TNonblockingServerTransport> serverTransport(new TNonblockingServerSocket(port)); stdcxx::shared_ptr<PlatformThreadFactory> threadFactory = std::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()); stdcxx::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(10); threadManager->threadFactory(threadFactory); threadManager->start(); stdcxx::shared_ptr<TNonblockingServer> server(new TNonblockingServer(processor, protocolFactory, serverTransport, threadManager)); server->serve(); return 0; } // g++ -g -I/usr/local/include/thrift gen-cpp/DemoService.cpp service.cpp -lthrift -L/usr/local/lib/*.so -o service