請直接使用便可,無需拉取任何依賴包。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