请直接使用便可,无需拉取任何依赖包。html
cd $GOPATH/src git clone https://github.com/hunterhug/thrift_example.git go build server.gp go build client.go ./server ./client
$GOPATH
为环境变量,请替换为你的本地路径。linux
gRPC是Google研究的RPC传输方案,thrift则是facebook, 你们都经过IDL(Interface Definition Language)接口定义语言来规范输入输出。ios
下载: https://thrift.apache.org/downloadc++
sudo apt-get install automake bison flex git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config build-essential g++ tar xvf thrift-0.12.0.tar.gz ./bootstrap.sh ./configure make sudo make install sudo ldconfig
Windows系统请直接安装二进制。git
新建 timeRPC.thrift
:github
service timeServe { i32 getCurrtentTime() }
您能够忽略 C++
部分,直接跳到 Golang
部分。golang
执行:apache
thrift --gen cpp timeRPC.thrift
在当前目录下生成一个叫作 "gen-cpp" 的文件夹,里面包含了须要的代码。bootstrap
├── timeRPC_constants.cpp ├── timeRPC_constants.h ├── timeRPC_types.cpp ├── timeRPC_types.h ├── timeServe.cpp ├── timeServe.h └── timeServe_server.skeleton.cpp
修改 timeServe_server.skeleton.cpp
:ubuntu
// This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. #include "timeServe.h" #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/server/TSimpleServer.h> #include <thrift/transport/TServerSocket.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; class timeServeHandler : virtual public timeServeIf { public: timeServeHandler() { // Your initialization goes here } int32_t getCurrtentTime() { // Your implementation goes here auto t = time(nullptr); printf("getCurrtentTime: %ld\n", t); return t; } }; int main(int argc, char **argv) { int port = 9090; ::apache::thrift::stdcxx::shared_ptr<timeServeHandler> handler(new timeServeHandler()); ::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new timeServeProcessor(handler)); ::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); ::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); ::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); server.serve(); return 0; }
咱们实现了 getCurrtentTime
这个方法。
编译:
g++ -std=c++11 -o cpp-server timeRPC_constants.cpp timeRPC_types.cpp timeServe.cpp timeServe_server.skeleton.cpp -lthrift
查看:
ldd cpp-server linux-vdso.so.1 => (0x00007ffee83b4000) libthrift-0.12.0.so => /usr/local/lib/libthrift-0.12.0.so (0x00007f0200e34000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0200ab2000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f020089c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f02004d2000) libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f0200269000) libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f01ffe24000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f01ffc07000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f01ff8fe000) /lib64/ld-linux-x86-64.so.2 (0x00007f02010fe000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f01ff6fa000)
运行:
./cpp-server
在 gen-cpp
上层新建 client.cpp
:
// system #include <iostream> // lib #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/transport/TSocket.h> #include <thrift/transport/TTransportUtils.h> #include <boost/shared_ptr.hpp> using namespace std; using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using boost::shared_ptr; // project #include "gen-cpp/timeServe.h" int main() { std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); std::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); timeServeClient client(protocol); // open connect transport->open(); auto timeNow = client.getCurrtentTime(); std::cout << timeNow << std::endl; transport->close(); return 0; }
对它进行编译:
g++ -std=c++11 -o cpp-client client.cpp gen-cpp/timeServe.cpp -lthrift
运行:
./cpp-client 1553223392
修改 timeRPC.thrift
:
service timeServe { i32 getCurrtentTime() } service time2Serve { i32 getCurrtentTime() }
查看:
go env GOPATH="/opt/gocode"
其中 $GOPATH
为 /opt/gocode
。
准备必要库:
mkdir -p $GOPATH/src/github.com/apache cd $GOPATH/src/github.com/apache git clone https://github.com/apache/thrift.git
执行:
thrift --gen go timeRPC.thrift
在当前目录下生成一个叫作 "gen-go" 的文件夹,里面包含了须要的代码。
└── timerpc ├── GoUnusedProtection__.go ├── timeRPC-consts.go ├── timeRPC.go └── time_serve-remote └── time_serve-remote.go
在 gen-go
上层新建 server.go
:
package main import ( "context" "fmt" "github.com/apache/thrift/lib/go/thrift" "net" "os" "thrift_example/gen-go/timerpc" "time" ) type MyTime struct{} func (s *MyTime) GetCurrtentTime(_ context.Context) (r int32, err error) { t := int32(time.Now().Unix()) fmt.Printf("come on:%d\n", t) return t, nil } type MyTime2 struct{} func (s *MyTime2) GetCurrtentTime(_ context.Context) (r int32, err error) { t := int32(time.Now().Unix()) fmt.Printf("come on2:%d\n", t) return t, nil } func main() { // 建立服务器 serverTransport, err := thrift.NewTServerSocket(net.JoinHostPort("127.0.0.1", "9090")) if err != nil { fmt.Println("Error!", err) os.Exit(1) } // 建立二进制协议 protocolFactory := thrift.NewTBinaryProtocolFactoryDefault() transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory()) // 建立Processor,用一个端口处理多个服务 multiProcessor := thrift.NewTMultiplexedProcessor() MyTimeProcessor := timerpc.NewTimeServeProcessor(new(MyTime)) MyTime2Processor := timerpc.NewTimeServeProcessor(new(MyTime2)) // 给每一个service起一个名字 multiProcessor.RegisterProcessor("mytime", MyTimeProcessor) multiProcessor.RegisterProcessor("mytime2", MyTime2Processor) server := thrift.NewTSimpleServer4(multiProcessor, serverTransport, transportFactory, protocolFactory) fmt.Println("start") if err := server.Serve(); err != nil { panic(err) } // 退出时中止服务器 defer server.Stop() }
编译并运行:
go build server.go ./server
在 gen-go
上层新建 client.go
:
package main import ( "context" "fmt" "github.com/apache/thrift/lib/go/thrift" "net" "os" "thrift_example/gen-go/timerpc" ) func main() { // 先创建和服务器的链接的socket,再经过socket创建Transport socket, err := thrift.NewTSocket(net.JoinHostPort("127.0.0.1", "9090")) if err != nil { fmt.Println("Error opening socket:", err) os.Exit(1) } transport := thrift.NewTFramedTransport(socket) // 建立二进制协议 protocol := thrift.NewTBinaryProtocolTransport(transport) // 打开Transport,与服务器进行链接 if err := transport.Open(); err != nil { fmt.Fprintln(os.Stderr, "Error opening socket to "+"localhost"+":"+"9090", err) os.Exit(1) } defer transport.Close() // 接口须要context,以便在长操做时用户能够取消RPC调用 ctx := context.Background() // 使用Mytime服务 MyTimeProtocol := thrift.NewTMultiplexedProtocol(protocol, "mytime") // 建立代理客户端,使用TMultiplexedProtocol访问对应的服务 c := thrift.NewTStandardClient(MyTimeProtocol, MyTimeProtocol) client := timerpc.NewTimeServeClient(c) res, err := client.GetCurrtentTime(ctx) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Println(res) // 使用其余服务 // 步骤与上面的相同 // 使用Mytime服务 MyTime2Protocol := thrift.NewTMultiplexedProtocol(protocol, "mytime2") c2 := thrift.NewTStandardClient(MyTime2Protocol, MyTime2Protocol) client2 := timerpc.NewTimeServeClient(c2) res, err = client2.GetCurrtentTime(ctx) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Println(res) }
编译并运行:
go build client.go ./client