需求:
在CPP服务端输入int,在ERL客户端显示。
实现:
1、编写thrift文件,一个命名为tutorial.thrift,一个命名为shared.thrift
tutorial.thrift
include "shared.thrift"
namespace cpp tutorial
namespace java tutorial
namespace php tutorial
namespace perl tutorial
namespace smalltalk.category Thrift.Tutorial
typedef i32 MyInteger
const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
service Calculator extends shared.SharedService
{
void ping(),
i32 add(),
oneway void zip()
}
shared.thrift
namespace cpp shared namespace java shared namespace perl shared struct SharedStruct { 1: i32 key 2: string value } service SharedService { SharedStruct getStruct(1: i32 key) }
2、编写CPP服务器端代码
#include <concurrency/ThreadManager.h>
#include <concurrency/PosixThreadFactory.h>
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <server/TThreadPoolServer.h>
#include <server/TThreadedServer.h>
#include <transport/TServerSocket.h>
#include <transport/TTransportUtils.h>
#include <iostream>
#include <stdexcept>
#include <sstream>
#include "../gen-cpp/Calculator.h"
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using namespace tutorial;
using namespace shared;
using namespace boost;
class CalculatorHandler : public CalculatorIf
{
public:
CalculatorHandler() {}
void ping()
{
printf("ping()\n");
}
int32_t add()
{
int32_t n;
cin>>n;
return n;
}
void getStruct(SharedStruct &ret, const int32_t logid) {
printf("getStruct(%d)\n", logid);
ret = log[logid];
}
void zip() {
printf("zip()\n");
}
protected:
map<int32_t, SharedStruct> log;
};
int main(int argc, char **argv) {
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
shared_ptr<CalculatorHandler> handler(new CalculatorHandler());
shared_ptr<TProcessor> processor(new CalculatorProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
TSimpleServer server(processor,
serverTransport,
transportFactory,
protocolFactory);
/**
* Or you could do one of these
shared_ptr<ThreadManager> threadManager =
ThreadManager::newSimpleThreadManager(workerCount);
shared_ptr<PosixThreadFactory> threadFactory =
shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
threadManager->threadFactory(threadFactory);
threadManager->start();
TThreadPoolServer server(processor,
serverTransport,
transportFactory,
protocolFactory,
threadManager);
TThreadedServer server(processor,
serverTransport,
transportFactory,
protocolFactory);
*/
printf("Starting the server...\n");
server.serve();
printf("done.\n");
return 0;
}
3、编写客户端ERL
-module(client). -include("calculator_thrift.hrl"). -export([t/0]). p(X) -> io:format("~p~n", [X]), ok. t() -> Port = 9090, {ok, Client} = thrift_client:start_link("127.0.0.1", Port, calculator_thrift), {ok, Sum} = thrift_client:call(Client, add, []), io:format("the information form cpp server is : ~p~n", [Sum]), ok = thrift_client:close(Client), ok.
存在问题:
1、ERL客户端会出现接收超时问题;
在thrift中,提供了三种服务器类型:
TSimpleServer:简单的单线程服务器,主要用于测试
TThreadPoolServer:使用标准阻塞式IO的多线程服务器
TNonblockingServer:使用非阻塞式IO的多线程服务器,TFramedTransport必须使用该类型的 server
但是,在ERL中,并没有发现这三种服务类型的设置,在CPP、C#、JAVA等中,都有这三种服务类型的设置。