打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用thrift作为go和C++中间rpc及问题(一) | Go语言中文网 | Golang中文社区 | Golang中国

使用thrift作为go和C++中间rpc及问题(一)

2015-09-25 16:48  hgd7123
阅读 2478 次  0 人喜欢  0 条评论  收藏

这两天因为工作需要查了一些跨语言的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 hellowordnamespace go hellowordservice 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 }

 

编译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++没有问题。


写GO的代码:

GO server端

package mainimport(	"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成大写。	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 mainimport(	"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)    }	 }

当然测试也没有问题。

 

下面就是交叉访问了。

当然基于以上代码同样没有问题,哈哈哈哈,因为问题被我K了啊 。附上截图。

C++ client端 与 GO server端

 

GO client VS C++ server 同样没有问题我就不截图了。

后面文章说下遇到的问题及分析。

 

本文来自:博客园

感谢作者:hgd7123

查看原文:使用thrift作为go和C++中间rpc及问题(一)

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
windows配置thrift开发环境
thrift笔记
Thrift初用小结
thrift 小结
使用Thrift RPC编写程序
PHP laravel+thrift+swoole打造微服务框架
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服