読者です 読者をやめる 読者になる 読者になる

複数のクライアントからThriftサーバに接続する方法(C++)

あんま書いてなかったので。Javaでは見つかったんだけどC++だと需要ないの?

  • calculator.thrift
namespace cpp example
service Calculator
{
    i64 add(1:i32 num1, 2:i32 num2);
}

適当に足し算するメソッドを用意する

  • server.cpp
#include "gen-cpp/Calculator.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/processor/TMultiplexedProcessor.h>
#include <iostream>
#include <thread>
#include <chrono>

using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using boost::shared_ptr;

using namespace ::example;

class CalculatorHandler : virtual public CalculatorIf{
public:
    CalculatorHandler(){}
    //addの実装
    int64_t add(const nt32_t num1, const int32_t num2){
        std::this_thread::sleep_for(std::chrono::milliseconds(2000));
        return num1 + num2;
    }
};

int main(int argc, char** argv)
{
    int port = 9090;
    shared_ptr<CalculatorHandler> handler(new CalculatorHandler());
    //実行するプロセスのインスタンスを複数用意する
    shared_ptr<TProcessor> processor(new CalculatorProcessor(handler));
    shared_ptr<TProcessor>remoteProcessor(new CalculatorProcessor(handler));

    shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
    //メインのプロセス
    shared_ptr<TMultiplexedProcessor> mprocessor(new TMultiplexedProcessor());
    //名前をつけてメインプロセスに実行プロセスを登録する
    mprocessor->registerProcessor("Calculator", processor);
    mprocessor->registerProcessor("remoteCalculator", processor);

    TSimpleServer server(mprocessor, serverTransport, transportFactory, protocolFactory);
    server.server();

    return 0;
}

  • client.cpp
#include <iostream>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transportt/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/protocol/TMultiplexedProtocol.h>

#include "gen-cpp/Calculator.h"

using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace ::example;

int main(int argc, char** argv)
{
    //ホントはちゃんと処理しないとだめだけど第一引数がプロセス名とする
    string protocolName = argv[1];

    boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
    boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    boost::shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport));
    //複数接続する用のプロトコルを使う。名前で識別する
    boost::shared_ptr<TMultiplexedProtocol> mp(new TMultiplexedProtocol(protocol, protocolName.c_str()));
    CalculatorClient client(mp);

    transport->open();
    int val = client.add(1, 2);
    std::cout << val << std::endl;
    transport->close();
    return 0;
}

マルチスレッドじゃないんで先に撮った方のプロセスの処理が終わるまで待ちが発生するけど、同じポートに二つのクライアントプロセスから接続して処理させるのはできました。あ、ビルド時にlibthread.aにリンクしてね