1. 程式人生 > >利用thrift rpc進行C++與Go的通信

利用thrift rpc進行C++與Go的通信

span 網絡 gen generate golang fun package should edt

一:什麽是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)

}

  

利用thrift rpc進行C++與Go的通信