Thrift C++服务器 Java 客户端 通信方法

在使用本内容前,需要安装 Thrift 

     首先编辑 一个接口文件 .thrift

    demo.thrift 代码如下:

struct UserProfile{
        1:i32 id, //注意这里是逗号,而不是分号
        2:string name,
        3:string blurb
} //这里没有分号
 
service UserStorage{
        void store(1: UserProfile user), //注意这里是逗号,而不是分号
        UserProfile getUser(1: i32 uid)
}

   运行如下命令:

# thrift -r --gen cpp demo.thrift

  可以看到在当前目录下产生了一个gen-cpp的目录,该目录下即以上命令产生的文件:

 UserStorage.cpp
 UserStorage.h
 UserStorage_server.skeleton.cpp
 demo_constants.cpp
 demo_constants.h
 demo_types.cpp
 demo_types.h

 注意:在以上文件中,只有UserStorage_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 "UserStorage.h"
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>
#include <map>
 
using namespace std;
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
 
using boost::shared_ptr;
 
class UserStorageHandler : virtual public UserStorageIf {
 public:
  UserStorageHandler() {
    // Your initialization goes here
  }
 
  void store(const UserProfile& user) {
    // Your implementation goes here
    printf("store\n");
  }
 
  void getUser(UserProfile& _return, const int32_t uid) {
    // Your implementation goes here
    printf("getUser\n");
  }
};
 
int main(int argc, char **argv) {
  int port = 9090;
  shared_ptr<UserStorageHandler> handler(new UserStorageHandler());
  shared_ptr<TProcessor> processor(new UserStorageProcessor(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;
}

  可以看到,该文件只是一个框架,用户可以根据需要扩展该文件,笔者修改如下(蓝色部分为添加的代码,同时将文件改名为 serStorage_server.cpp):

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

#include "UserStorage.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <map>

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

using boost::shared_ptr;

class UserStorageHandler : virtual public UserStorageIf {

 public:
  UserStorageHandler() {
    // Your initialization goes here
  }

  void store(const UserProfile& user) {
    // Your implementation goes here
    log[user.id] = user;
    printf("store\n");
  }

  void getUser(UserProfile& _return, const int32_t uid) {
    // Your implementation goes here
    _return = log[uid];
    printf("getUser\n");
  }

  protected:
        map<int32_t, UserProfile> log;

};

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

  

C++客户端实现

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TTransportUtils.h>

#include "UserStorage.h"
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace boost;
int main(int argc, char** argv) {
  shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
  shared_ptr<TTransport> transport(new TBufferedTransport(socket)); 
  shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); //传输格式
  UserStorageClient client(protocol);
  try {
    transport->open();
        UserProfile user;
        user.id = 1;
        user.name = "liqb";
        user.blurb = "aaaaaa";
        client.store(user);
        UserProfile user2;
        client.getUser(user2, 1);
        printf("user.id = %d user.name = %s user.blurb = %s\n", user2.id, user2.name.c_str(), user2.blurb.c_str());
    transport->close();
  } catch (TException &tx) {
    printf("ERROR: %s\n", tx.what());
  }
}


 Makefile: 编译C++ 服务端和C++客户端

#BOOST_DIR = /usr/local/boost/include/boost-1_33_1/
THRIFT_DIR = /usr/local/include/thrift
LIB_DIR = /usr/local/lib
GEN_SRC = UserStorage.cpp demo_constants.cpp demo_types.cpp
default: server client
server: UserStorage_server.cpp
	g++ -o CppServer   -I../gen-cpp -I${THRIFT_DIR} -L${LIB_DIR} -lthrift UserStorage_server.cpp ${GEN_SRC}
client: CppClient.cpp
	g++ -o CppClient   -I../gen-cpp -I${THRIFT_DIR} -L${LIB_DIR} -lthrift CppClient.cpp ${GEN_SRC}
clean:
	$(RM) -r CppClient CppServer


  Java客户端实现

   到thrift-x.x.x/tutorial/java/src/拷贝:JavaClient.java

 重命名为:UserProfileClient.java 

import org.apache.thrift.TException;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;

public class UserProfileClient {
  public static void main(String [] args) {

    /*if (args.length != 1) {
      System.out.println("Please enter 'simple' or 'secure'");
      System.exit(0);
    }  */ 

    try {
      TTransport transport;
      //if (args[0].contains("simple")) {
        transport = new TSocket("localhost", 9090);
        transport.open();
      //}   
      //else {
        /*  
         * Similar to the server, you can use the parameters to setup client parameters or
         * use the default settings. On the client side, you will need a TrustStore which
         * contains the trusted certificate along with the public key. 
         * For this example it's a self-signed cert. 
         */
        //TSSLTransportParameters params = new TSSLTransportParameters();
        //params.setTrustStore("../../lib/java/test/.truststore", "thrift", "SunX509", "JKS");
        /*  
         * Get a client transport instead of a server transport. The connection is opened on
         * invocation of the factory method, no need to specifically call open()
         */
        //transport = TSSLTransportFactory.getClientSocket("localhost", 9091, 0, params);
      //}   

      TProtocol protocol = new  TBinaryProtocol(transport);
      UserStorage.Client client = new UserStorage.Client(protocol);

      int uid=123;
      System.out.println(client.getUser(uid));

      UserProfile u = new UserProfile();
      u.id=999;
      u.name="kaining";
      u.blurb="test 999"; 
      client.store(u);

      transport.close();
    } catch (TException x) {
      x.printStackTrace();
    }   
  }
}

  

  编译Java客户端需要使用Thrift Java 库,可以使用Maven

<dependency>
	<groupId>org.apache.thrift</groupId>
	<artifactId>libthrift</artifactId>
	<version>0.9.3</version>
</dependency>

 

 编译成功后便可以通讯了














你可能感兴趣的:(Thrift C++服务器 Java 客户端 通信方法)