选择thrift作为go和C++中间rpc及问题

旋即有限上因做事需查阅了片跨语言的rpc接口。我这边因的是富含连串化和tcp交互的。

重大查看了瞬间以下三看似:

1.ICE 随即玩意不帮助go,直接抛弃。

2.GRPC,这东西刚刚宣布,还都到采用C++11特色,我们生育条件时还没升级,他仗让protobuf
3.0.0版本,那个要beta版,拿过来编译了下,看重google的gmock。我之虚拟机上并不上,只可以暂时作罢。

3.Thrift,这多少个由0.9.1 就起周密(官方)襄助go语言了,这便将这操刀吧。

 

流淌:C++测试环境ubuntu12.04LTS  内核 3.2.0-23 GCC版本4.6.3
 Go就当win7台式机及走的。

率先码事安装thrift,从官网下载最新thrift0.9.2版本。

编译安装参考 http://my.oschina.net/zc741520/blog/399049

libevent库我当下面前段时间用到了不畏不用安装了,使用的版是2.0.22-stable

 

GO版本thrift从之地方

git-wip-us.apache.org/repos/asf/thrift.git/lib/go/thrift获取哦 
git.apache.org/thrift.git/lib/go/thrift永远超时。

thrift文件如下:

namespace cpp helloword
namespace go helloword

service Test
{
    string hello(1: string data);
}

我把world写错了…=_=!

thrift –gen cpp helloword.thrift  

thrift –gen go helloword.thrift

扭转的C++文件么有题目,go里面要修改下test.go和contants.go的thrift库的职

import(
    "helloword"
    "fmt"
    "git-wip-us.apache.org/repos/asf/thrift.git/lib/go/thrift"
    "os"
    "net"
)

 

脚开首撸C++代码了。

C++ server端代码

 1 #include <thrift/concurrency/ThreadManager.h>
 2 #include <thrift/concurrency/PosixThreadFactory.h>
 3 #include <thrift/protocol/TBinaryProtocol.h>
 4 #include <thrift/server/TSimpleServer.h>
 5 #include <thrift/server/TThreadPoolServer.h>
 6 #include <thrift/server/TThreadedServer.h>
 7 #include <thrift/transport/THttpServer.h>
 8 #include <thrift/transport/TServerSocket.h>
 9 #include <thrift/concurrency/ThreadManager.h>
10 #include <thrift/concurrency/PosixThreadFactory.h>
11 #include <thrift/protocol/TBinaryProtocol.h>
12 #include <thrift/server/TSimpleServer.h>
13 #include <thrift/server/TThreadPoolServer.h>
14 #include <thrift/server/TThreadedServer.h>
15 #include <thrift/transport/THttpServer.h>
16 #include <thrift/transport/TServerSocket.h>
17 #include <thrift/transport/TTransportUtils.h>
18 #include <thrift/TToString.h>
19 #include <iostream>
20 #include <string>
21 #include "Test.h"
22 #include <boost/bind.hpp>
23 #include <boost/function.hpp>
24 #include <thrift/protocol/TBinaryProtocol.h>
25 #include <thrift/transport/TSocket.h>
26 #include <thrift/transport/TTransportUtils.h>
27 using namespace std;
28 using namespace apache::thrift;
29 using namespace apache::thrift::concurrency;
30 using namespace apache::thrift::protocol;
31 using namespace apache::thrift::transport;
32 using namespace apache::thrift::server;
33 using namespace ::apache::thrift;
34 using namespace ::apache::thrift::protocol;
35 using namespace ::apache::thrift::transport;
36 using namespace ::boost;
37 using namespace ::helloword;
38 using ::boost::bind;
39 
40 class TestHandler : virtual public TestIf {
41  public:
42   TestHandler() { }
43 
44   void hello(std::string& _return, const std::string& data) {
45 //    if(data=="ping")
46       printf("[%d] recv ping\n", (int)time(NULL));
47   _return = "pong";
48   printf("[%d] send pong\n", (int)time(NULL));
49 }};
50 
51 int main(int argc, char **argv) {
52   int port = 9000;
53   shared_ptr<TestHandler> handler(new TestHandler());
54   shared_ptr<TProcessor> processor(new TestProcessor(handler));
55   shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
56   shared_ptr<TTransportFactory> transportFactory(new TTransportFactory());
57   shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
58   TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
59   server.serve();
60   return 0;
61 }

C++ Client端代码

 1 #include <iostream>
 2 #include <string>
 3 #include <thrift/protocol/TBinaryProtocol.h>
 4 #include <thrift/transport/TSocket.h>
 5 #include <thrift/transport/TTransportUtils.h>
 6 #include "Test.h"
 7 using namespace std;
 8 using namespace apache::thrift;
 9 using namespace apache::thrift::protocol;
10 using namespace apache::thrift::transport;
11 using namespace helloword;
12 int main(int argc,char ** argv) {
13         string server = "127.0.0.1";
14         if(argc>1)server= argv[1];
15         boost::shared_ptr<TTransport> socket(new TSocket(server, 9000));
16         boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
17         boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
18         TestClient client(protocol);
19 try {
20         transport->open();
21         string cao="haha";
22         client.hello(cao,cao);
23         cout << "Hello"<< cao << endl;
24 }
25 catch(apache::thrift::TApplicationException &e)
26 {
27 cout<<e.what()<<endl;
28 }
29         return 0;
30 }

C++, 

编译server端

g++ -o server server.cpp Test.cpp helloword_constants.cpp helloword_types.cpp -lthrift -lboost_system

编译Client端

g++ -o client client.cpp Test.cpp helloword_constants.cpp helloword_types.cpp -lthrift -lboost_system

测试C++没有问题。

C++ 1

C++ 2

C++ 3

写GO的代码:

GO server端

package main

import(
    "helloword"
    "fmt"
    "git-wip-us.apache.org/repos/asf/thrift.git/lib/go/thrift"
    "os"

)

const (
    NetworkAddr = "192.168.20.76:9000"
)

type Test struct{
}

func (this *Test) Hello(data string)(r string, err error){  //注意这里,我的thrift代码里面写的接口时小写的hello 在test.go里面被fmt成大写。 这里因为C++ 支持大小写,而Go 默认对外导出函数是大写,所以接口尽量定义成大写保持一致,不然容易出现 thrift 接口不存在异常
    fmt.Println("rec", data)
    r = data+"haha"
    fmt.Println("send", r)
    return
}

func main(){
    transportFactory := thrift.NewTTransportFactory()
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    //protocolFactory := thrift.NewTCompactProtocolFactory()

    serverTransport, err := thrift.NewTServerSocket(NetworkAddr)
    if err != nil {
        fmt.Println("Error!", err)
        os.Exit(1)
    }

    handler := &Test{}
    processor := helloword.NewTestProcessor(handler)

    server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory)
    fmt.Println("thrift server in", NetworkAddr)
    server.Serve()
}

GO client代码

package main

import(
    "helloword"
    "fmt"
    "git-wip-us.apache.org/repos/asf/thrift.git/lib/go/thrift"
    "os"
    "net"
)

func main (){
    transportFactory := thrift.NewTTransportFactory()
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    transport ,err := thrift.NewTSocket(net.JoinHostPort("127.0.0.1","9000"))

    if err != nil {
        fmt.Fprintln(os.Stderr, "error resolving address:", err)
        os.Exit(1)
    }

     useTransport := transportFactory.GetTransport(transport)
     client := helloword.NewTestClientFactory(useTransport, protocolFactory)
    if err := transport.Open(); err != nil {
        fmt.Fprintln(os.Stderr, "Error opening socket to server", " ", err)
        os.Exit(1)
    }
    defer transport.Close()

    for i := 0; i < 2; i++ {
        r1, e1 := client.Hello("hello")
        fmt.Println(i, "Call->", r1, e1)
    }


}

本测试为一直不问题。

C++ 4

 

下边就穿插访问了。

当基于上述代码同样没问题 。附上截图。

C++ client端 与 GO server端

C++ 5

C++ 6

 

GO client VS C++ server 同样无问题我便不截图了。