欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CPP服务端++thrift++erl客户端

程序员文章站 2022-07-13 10:59:00
...

需求:

        在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等中,都有这三种服务类型的设置。