Thrift RPC Golang、C++ Example

Thrift RPC Example

run

Please be directly used without pulling any dependencies.

cd $GOPATH/src

git clone https://github.com/hunterhug/thrift_example.git

go build server.gp
go build client.go

./server
./client

$GOPATH Environment variables, replace your local path.

Specific use, details

gRPC transmission scheme is RPC Google research, thrift is facebook, we have to regulate the input and output via IDL (Interface Definition Language) interface definition language.

Download: https://thrift.apache.org/download

Ubuntu system installation

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

Please install Windows system binaries directly.

Establish thrift file

New timeRPC.thrift:

service timeServe {
    i32 getCurrtentTime()
}

C ++ server

You can ignore the C++section, jump directly to the Golangsection.

carried out:

thrift --gen cpp timeRPC.thrift

In the current directory called "gen-cpp" folder, which contains the code needed.

├── timeRPC_constants.cpp
├── timeRPC_constants.h
├── timeRPC_types.cpp
├── timeRPC_types.h
├── timeServe.cpp
├── timeServe.h
└── timeServe_server.skeleton.cpp

Modify timeServe_server.skeleton.cpp:

// 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;
}

We achieved getCurrtentTimethis way.

Compile:

g++ -std=c++11 -o cpp-server timeRPC_constants.cpp timeRPC_types.cpp timeServe.cpp timeServe_server.skeleton.cpp -lthrift

View:

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)

run:

./cpp-server

C ++ client

In gen-cppupper New 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;
}

Compile it:

g++ -std=c++11 -o cpp-client client.cpp gen-cpp/timeServe.cpp  -lthrift

run:

./cpp-client 
1553223392

Golang server

Modify timeRPC.thrift:

service timeServe {
    i32 getCurrtentTime()
}


service time2Serve {
    i32 getCurrtentTime()
}

View:

go env

GOPATH="/opt/gocode"

Which $GOPATHis /opt/gocode.

To prepare the necessary library:

mkdir -p $GOPATH/src/github.com/apache
cd $GOPATH/src/github.com/apache
git clone https://github.com/apache/thrift.git

carried out:

thrift --gen go timeRPC.thrift

In the current directory called "gen-go" folder, which contains the code needed.

└── timerpc
    ├── GoUnusedProtection__.go
    ├── timeRPC-consts.go
    ├── timeRPC.go
    └── time_serve-remote
        └── time_serve-remote.go

In gen-goupper New 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()
}

Compile and run:

go build server.go
./server

Golang client

In gen-goupper New 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)
}

Compile and run:

go build client.go
./client

Reproduced please specify: http://www.lenggirl.com/cap/thrift.html

Guess you like

Origin www.cnblogs.com/nima/p/11750942.html