thrift使用说明

thrift 下载网址: http://archive.apache.org/dist/thrift/0.9.3/

需要下载的依赖库有:openssl-1.0.2o-- 、thrift-0.9.3、libevent-2.1.8-stable、boost_1_66_0--其中依赖库也需要生成LIB来进行调用。

1.编译BOOST: 编译好后,自己用一下 ,可以写一个简单的demo

关于boost的编译,参见  https://blog.csdn.net/ljt350740378/article/details/87091133

2.编译openssl-1.0.2o : 编译好后,自己用一下 ,可以写一个简单的demo

参见  https://blog.csdn.net/ljt350740378/article/details/87807544

2.编译 libevent-2.1.8-stable: 编译好后,自己用一下 ,可以写一个简单的demo

编译 libevent-2.1.8-stable,其中可以把 openssl嵌套编译进去,如下图:参见 https://blog.csdn.net/ljt350740378/article/details/87856875

3.下载thrift

http://thrift.apache.org/download     thrift-0.12.0.tar.gz    和    thrift-0.12.0.exe

E:\canDel\thrift-0.12.0\tutorial\cpp 里面有例子教程

参考 https://github.com/Zuolijia/thrift       

https://blog.csdn.net/zuolj/article/details/77450108

4.编译thrift

打开工程,如下所示: E:\canDel\thrift-0.12.0\lib\cpp\thrift.sln

thrift命令:

thrift --gen cpp xxx.thrift                            #Linux下
thrift-0.9.3.exe --gen cpp xxx.thrift                      #Windows下
thrift-0.9.3.exe -r -strict --gen cpp:cob_style xxx.thrift #异步

然后其中:添加包含目录: $(ProjectDir)\src\;$(ProjectDir)\src\thrift\windows\;E:\canDel\boost_1_59_0\;E:\canDel\libevent-2.1.9-beta\openssl\inc32\include;E:\canDel\libevent-2.1.9-beta\;E:\canDel\libevent-2.1.9-beta\include;E:\canDel\libevent-2.1.9-beta\WIN32-Code\nmake\;$(IncludePath)

库目录:$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);E:\canDel\libevent-2.1.9-beta;E:\canDel\libevent-2.1.9-beta\openssl\inc32\lib;

附加依赖库:libevent.lib;libevent_core.lib;libevent_extras.lib;libevent_openssl.lib;libeay32.lib;ssleay32.lib;

将E:\canDel\thrift-0.12.0\config.h 放入 E:\canDel\thrift-0.12.0\lib\cpp\src\thrift 中。

有时候 会出现错误,如:错误    1    error C1083: 无法打开包括文件: “netinet/in.h”: No such file or directory    E:\canDel\thrift-0.12.0\lib\cpp\src\thrift\Thrift.h    32    1    libthrift
类似这样的错误,把相对就的宏在 config.h 中注释起来即可。

编译:生成: E:\canDel\thrift-0.12.0\lib\cpp\x64\Release\libthriftnb.lib  E:\canDel\thrift-0.12.0\lib\cpp\x64\Release\libthrift.lib

5.调用thrift:

调用:
Hello.thrift 文件内容如下:
 

/*namespace cpp HelloThrift.Interface
service HelloService{
    string HelloString(1:string para)
    i32 HelloInt(1:i32 para)
    bool HelloBoolean(1:bool para)
    void HelloVoid()
    string HelloNull()
}
*/

/*
struct  ReResult
{
 1:i16 iReMessageType,
 2:string strReMessageData,
}

service  HelloService
{
	 ReResult DataTransfer(1:i16 iMessageType, 2:string strMessageData);
}
*/

service  HelloService
{
	 i16 addxy(1:i16 x, 2:i16 y);
}

命令如下:E:\canDel\thrift-0.12.0\lib\cpp\x64\Release>E:\canDel\thrift-0.12.0\lib\cpp\x64\Release\thrift-0.12.0.exe  --gen cpp Hello.thrift

生成的文件如下 :

其中,HelloService_server.skeleton.cpp 为生成的server的代码,直接拿过来用,并在里面写上实现代码就可以。

使用的工程添加 的包含目录 为:$(VC_IncludePath);$(WindowsSDK_IncludePath);E:\canDel\thrift-0.12.0\lib\cpp\src;E:\canDel\boost_1_59_0\;

库目录 为:$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);E:\canDel\thrift-0.12.0\lib\cpp\x64\Release;D:\boost\boost_1_59_0\bin\vc12-x64\lib;

依赖的LIB为:libthrift.lib;libthriftnb.lib;libboost_thread-vc120-mt-1_59.lib;

下面编写调用thrift代码:

server方面:HelloService_server.skeleton.cpp直接拿过来用,里面有main,直接用,添加所有gen-cpp下的7个文件到server的文件夹下面,并更改 HelloService_server.skeleton.cpp 为  server.cpp 代码如下:

server.cpp:

// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.

#if 0
#include "HelloService.h"
#include <thrift/transport/TBufferTransports.h>
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TThreadedServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/TToString.h>
#include <thrift/stdcxx.h>

#include <iostream>
#include <stdexcept>
#include <sstream>

//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  ::HelloThrift::Interface;

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

//using namespace tutorial;
//using namespace shared;
//using namespace  ::HelloThrift::Interface;
using namespace  HelloThrift;
using namespace  HelloThrift::Interface;;

class HelloServiceHandler : virtual public HelloServiceIf {
 public:
  HelloServiceHandler() {
    // Your initialization goes here
  }

  void HelloString(std::string& _return, const std::string& para) {
    // Your implementation goes here
    printf("HelloString,I got your name %s\n",para.c_str());
	_return = "give you back";
  }

  int32_t HelloInt(const int32_t para) {
    // Your implementation goes here
    printf("HelloInt\n");
	return para;
  }

  bool HelloBoolean(const bool para) {
    // Your implementation goes here
    printf("HelloBoolean\n");
	return para;
  }

  void HelloVoid() {
    // Your implementation goes here
    printf("HelloVoid\n");
  }

  void HelloNull(std::string& _return) {
    // Your implementation goes here
    printf("HelloNull\n");
  }

};

int main(int argc, char **argv) {
  int port = 9090;
  shared_ptr<HelloServiceHandler> handler(new HelloServiceHandler());
  shared_ptr<TProcessor> processor(new HelloServiceProcessor(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;
}

#endif


#include "HelloService.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 HelloServiceHandler : virtual public HelloServiceIf {
public:
	HelloServiceHandler() {
		// Your initialization goes here
	}

	int16_t addxy(const int16_t x, const int16_t y) {
		// Your implementation goes here
		return x + y;
		printf("addxy\n");
	}

};

int main(int argc, char **argv) 
{
	printf("hello i am server\n");
	int port = 9090;
	::apache::thrift::stdcxx::shared_ptr<HelloServiceHandler> handler(new HelloServiceHandler());
	::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new HelloServiceProcessor(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;
}

其中client一样,只是需要自己写client.cpp,图如下:

client.cpp代码如下:

#include "HelloService.h"
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TThreadedServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/TToString.h>
#include <thrift/stdcxx.h>
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <stdint.h>

using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::concurrency;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using boost::shared_ptr;

int main(int argc, char** argv)
{
	stdcxx::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
	stdcxx::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
	stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
	HelloServiceClient client(protocol);

	try
	{
		transport->open();
		int16_t x = 8;
		int16_t y = 87;
		int16_t ret = client.addxy(x, y);
		printf("testClient11111  %d\n", ret);
		getchar();
		transport->close();
	}
	catch (TException& tx)
	{
		printf("ERROR:%s\n", tx.what());
	}
}

E:\canDel\thrift-0.12.0\tutorial\cpp\CppServer.cpp中有多种server的工作模式,运行会有不同的效果,CppServer.cpp如下所示:

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TThreadedServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/TToString.h>
#include <thrift/stdcxx.h>

#include <iostream>
#include <stdexcept>
#include <sstream>

#include "../gen-cpp/Calculator.h"

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

using namespace tutorial;
using namespace shared;

class CalculatorHandler : public CalculatorIf {
public:
  CalculatorHandler() {}

  void ping() { cout << "ping()" << endl; }

  int32_t add(const int32_t n1, const int32_t n2) {
    cout << "add(" << n1 << ", " << n2 << ")" << endl;
    return n1 + n2;
  }

  int32_t calculate(const int32_t logid, const Work& work) {
    cout << "calculate(" << logid << ", " << work << ")" << endl;
    int32_t val;

    switch (work.op) {
    case Operation::ADD:
      val = work.num1 + work.num2;
      break;
    case Operation::SUBTRACT:
      val = work.num1 - work.num2;
      break;
    case Operation::MULTIPLY:
      val = work.num1 * work.num2;
      break;
    case Operation::DIVIDE:
      if (work.num2 == 0) {
        InvalidOperation io;
        io.whatOp = work.op;
        io.why = "Cannot divide by 0";
        throw io;
      }
      val = work.num1 / work.num2;
      break;
    default:
      InvalidOperation io;
      io.whatOp = work.op;
      io.why = "Invalid Operation";
      throw io;
    }

    SharedStruct ss;
    ss.key = logid;
    ss.value = to_string(val);

    log[logid] = ss;

    return val;
  }

  void getStruct(SharedStruct& ret, const int32_t logid) {
    cout << "getStruct(" << logid << ")" << endl;
    ret = log[logid];
  }

  void zip() { cout << "zip()" << endl; }

protected:
  map<int32_t, SharedStruct> log;
};

/*
  CalculatorIfFactory is code generated.
  CalculatorCloneFactory is useful for getting access to the server side of the
  transport.  It is also useful for making per-connection state.  Without this
  CloneFactory, all connections will end up sharing the same handler instance.
*/
class CalculatorCloneFactory : virtual public CalculatorIfFactory {
 public:
  virtual ~CalculatorCloneFactory() {}
  virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
  {
    stdcxx::shared_ptr<TSocket> sock = stdcxx::dynamic_pointer_cast<TSocket>(connInfo.transport);
    cout << "Incoming connection\n";
    cout << "\tSocketInfo: "  << sock->getSocketInfo() << "\n";
    cout << "\tPeerHost: "    << sock->getPeerHost() << "\n";
    cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
    cout << "\tPeerPort: "    << sock->getPeerPort() << "\n";
    return new CalculatorHandler;
  }
  virtual void releaseHandler( ::shared::SharedServiceIf* handler) {
    delete handler;
  }
};

int main() {
  TThreadedServer server(
    stdcxx::make_shared<CalculatorProcessorFactory>(stdcxx::make_shared<CalculatorCloneFactory>()),
    stdcxx::make_shared<TServerSocket>(9090), //port
    stdcxx::make_shared<TBufferedTransportFactory>(),
    stdcxx::make_shared<TBinaryProtocolFactory>());

  /*
  // if you don't need per-connection state, do the following instead
  TThreadedServer server(
    stdcxx::make_shared<CalculatorProcessor>(stdcxx::make_shared<CalculatorHandler>()),
    stdcxx::make_shared<TServerSocket>(9090), //port
    stdcxx::make_shared<TBufferedTransportFactory>(),
    stdcxx::make_shared<TBinaryProtocolFactory>());
  */

  /**
   * Here are some alternate server types...

  // This server only allows one connection at a time, but spawns no threads
  TSimpleServer server(
    stdcxx::make_shared<CalculatorProcessor>(stdcxx::make_shared<CalculatorHandler>()),
    stdcxx::make_shared<TServerSocket>(9090),
    stdcxx::make_shared<TBufferedTransportFactory>(),
    stdcxx::make_shared<TBinaryProtocolFactory>());

  const int workerCount = 4;

  stdcxx::shared_ptr<ThreadManager> threadManager =
    ThreadManager::newSimpleThreadManager(workerCount);
  threadManager->threadFactory(
    stdcxx::make_shared<PlatformThreadFactory>());
  threadManager->start();

  // This server allows "workerCount" connection at a time, and reuses threads
  TThreadPoolServer server(
    stdcxx::make_shared<CalculatorProcessorFactory>(stdcxx::make_shared<CalculatorCloneFactory>()),
    stdcxx::make_shared<TServerSocket>(9090),
    stdcxx::make_shared<TBufferedTransportFactory>(),
    stdcxx::make_shared<TBinaryProtocolFactory>(),
    threadManager);
  */

  cout << "Starting the server..." << endl;
  server.serve();
  cout << "Done." << endl;
  return 0;
}

运行时,先运行server,再运行client.OK.如果有两个client,server只能响应一个client,如果把其中一个关了,就会响应后面的。

后来又新建了一个client2工程,但是没有调用成功。下面查看原因--没有调用异步模式参考:https://blog.csdn.net/whycold/article/details/11019967

https://blog.csdn.net/u201012980/article/details/51867864

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值