一:什么是rpc
rpc通俗来理解就是远程调用函数,相对于本地调用来说,只需要在主调函数中调用被掉函数即可,代码如下:
1 void fun(int i) 2 { 3 cout << "function call" << endl; 4 cout << "args: " << i << endl; 5 return; 6 } 7 8 int main() 9 { 10 fun(5); 11 return 0; 12 }
在上面的代码中,main( )函数在第10行调用了本地函数fun( ),本地调用就是这么简单。如果要远程调用一个函数,那么就需要进行网络通信,网络通信就设计到了网络编程,网络编程中有一本著名的经典书籍:《UNIX网络编程》,简称UNP,这本书基本上是系统层网络编程人员必读书籍,但是读过这本书的人都知道,网络的细节很多,也较复杂,如果每个项目都需要亲自写这些底层实现,那无疑大大延缓了项目开发进度,而且很多上层开发人员不懂得这些细节。解决办法就是造轮子,以库的形式封装这些底层细节,屏蔽掉底层,让其他开发人员可以简单直接使用。
二:thrift的安装
thrift就是前面提到的一种rpc库。,它是跨语言的,并且是C/S模式。
三:利用thrift进行C++与Go通信
C++服务端:
// This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. // system #include <time.h> #include <unistd.h> // lib #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; using boost::shared_ptr; // project #include "/home/archer/develop/thrift/gen-cpp/timeServe.h" using namespace utilityOfTime; class timeServeHandler : virtual public timeServeIf { public: timeServeHandler() { // Your initialization goes here } int32_t getCurrtentTime() { // Your implementation goes here printf("getCurrtentTime\n"); sleep(1); return time(nullptr); } }; int main() { int port = 9090; shared_ptr<timeServeHandler> handler(new timeServeHandler()); shared_ptr<TProcessor> processor(new timeServeProcessor(handler)); shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); server.serve(); return 0; }
C++客户端:
// system #include <iostream> // lib #include <thrift/protocol/TBinaryProtocol.h> #include <thrift/transport/TSocket.h> #include <thrift/transport/TTransportUtils.h> using namespace apache::thrift; using namespace apache::thrift::protocol; using namespace apache::thrift::transport; using boost::shared_ptr; // project #include "timeServe.h" using namespace utilityOfTime; int main() { // get socket shared_ptr<TTransport> socket(new TSocket("127.0.0.1", 9090)); // choose transport shared_ptr<TTransport> transport(new TBufferedTransport(socket)); // serialize 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; }
Golang客户端:
package main import ( "fmt" "git.apache.org/thrift.git/lib/go/thrift" "os" "timeserve" ) func main() { // get socket socket, err := thrift.NewTSocket("127.0.0.1:9090") // choose transport transport := thrift.NewTBufferedTransport(socket, 8192) // serialize protocolFactory := thrift.NewTBinaryProtocolFactoryDefault() client := timeserve.NewTimeServeClientFactory(transport, protocolFactory) // open connect transport.Open() defer socket.Close() timeResult, err := client.GetCurrtentTime() if err != nil { fmt.Println(err.Error()) os.Exit(2) } fmt.Println(timeResult) }