Thrift RPC Example

运行

请直接使用即可,无需拉取任何依赖包。

cd $GOPATH/src

git clone https://github.com/hunterhug/thrift_example.git

go build server.gp
go build client.go ./server
./client

$GOPATH 为环境变量,请替换为你的本地路径。

具体使用,详细介绍

gRPC是Google研究的RPC传输方案,thrift则是facebook, 大家都通过IDL(Interface Definition Language)接口定义语言来规范输入输出。

下载: https://thrift.apache.org/download

Ubuntu 系统安装

sudo apt-get install automake bison flex git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config build-essential g++

tar xvf thrift-0.12.0.tar.gz
./bootstrap.sh
./configure
make
sudo make install
sudo ldconfig

Windows系统请直接安装二进制。

建立 thrift 文件

新建 timeRPC.thrift:

service timeServe {
i32 getCurrtentTime()
}

C++ 服务端

您可以忽略 C++ 部分,直接跳到 Golang 部分。

执行:

thrift --gen cpp timeRPC.thrift

在当前目录下生成一个叫做 "gen-cpp" 的文件夹,里面包含了需要的代码。

├── timeRPC_constants.cpp
├── timeRPC_constants.h
├── timeRPC_types.cpp
├── timeRPC_types.h
├── timeServe.cpp
├── timeServe.h
└── timeServe_server.skeleton.cpp

修改 timeServe_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 "timeServe.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 timeServeHandler : virtual public timeServeIf {
public:
timeServeHandler() {
// Your initialization goes here
} int32_t getCurrtentTime() {
// Your implementation goes here
auto t = time(nullptr);
printf("getCurrtentTime: %ld\n", t);
return t;
} }; int main(int argc, char **argv) {
int port = 9090;
::apache::thrift::stdcxx::shared_ptr<timeServeHandler> handler(new timeServeHandler());
::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new timeServeProcessor(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;
}

我们实现了 getCurrtentTime这个方法。

编译:

g++ -std=c++11 -o cpp-server timeRPC_constants.cpp timeRPC_types.cpp timeServe.cpp timeServe_server.skeleton.cpp -lthrift

查看:

ldd cpp-server
linux-vdso.so.1 => (0x00007ffee83b4000)
libthrift-0.12.0.so => /usr/local/lib/libthrift-0.12.0.so (0x00007f0200e34000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0200ab2000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f020089c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f02004d2000)
libssl.so.1.0.0 => /lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007f0200269000)
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f01ffe24000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f01ffc07000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f01ff8fe000)
/lib64/ld-linux-x86-64.so.2 (0x00007f02010fe000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f01ff6fa000)

运行:

./cpp-server

C++客户端

gen-cpp 上层新建 client.cpp:

// system
#include <iostream> // lib
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using boost::shared_ptr; // project
#include "gen-cpp/timeServe.h" int main() {
std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); timeServeClient client(protocol); // open connect
transport->open();
auto timeNow = client.getCurrtentTime();
std::cout << timeNow << std::endl;
transport->close();
return 0;
}

对它进行编译:

g++ -std=c++11 -o cpp-client client.cpp gen-cpp/timeServe.cpp  -lthrift

运行:

./cpp-client
1553223392

Golang服务端

修改 timeRPC.thrift:

service timeServe {
i32 getCurrtentTime()
} service time2Serve {
i32 getCurrtentTime()
}

查看:

go env

GOPATH="/opt/gocode"

其中 $GOPATH/opt/gocode

准备必要库:

mkdir -p $GOPATH/src/github.com/apache
cd $GOPATH/src/github.com/apache
git clone https://github.com/apache/thrift.git

执行:

thrift --gen go timeRPC.thrift

在当前目录下生成一个叫做 "gen-go" 的文件夹,里面包含了需要的代码。

└── timerpc
├── GoUnusedProtection__.go
├── timeRPC-consts.go
├── timeRPC.go
└── time_serve-remote
└── time_serve-remote.go

gen-go 上层新建 server.go:

package main

import (
"context"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
"net"
"os"
"thrift_example/gen-go/timerpc"
"time"
) type MyTime struct{} func (s *MyTime) GetCurrtentTime(_ context.Context) (r int32, err error) {
t := int32(time.Now().Unix())
fmt.Printf("come on:%d\n", t)
return t, nil
} type MyTime2 struct{} func (s *MyTime2) GetCurrtentTime(_ context.Context) (r int32, err error) {
t := int32(time.Now().Unix())
fmt.Printf("come on2:%d\n", t)
return t, nil
} func main() {
// 创建服务器
serverTransport, err := thrift.NewTServerSocket(net.JoinHostPort("127.0.0.1", "9090"))
if err != nil {
fmt.Println("Error!", err)
os.Exit(1)
} // 创建二进制协议
protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory()) // 创建Processor,用一个端口处理多个服务
multiProcessor := thrift.NewTMultiplexedProcessor()
MyTimeProcessor := timerpc.NewTimeServeProcessor(new(MyTime))
MyTime2Processor := timerpc.NewTimeServeProcessor(new(MyTime2)) // 给每个service起一个名字
multiProcessor.RegisterProcessor("mytime", MyTimeProcessor)
multiProcessor.RegisterProcessor("mytime2", MyTime2Processor) server := thrift.NewTSimpleServer4(multiProcessor, serverTransport, transportFactory, protocolFactory) fmt.Println("start")
if err := server.Serve(); err != nil {
panic(err)
} // 退出时停止服务器
defer server.Stop()
}

编译并运行:

go build server.go
./server

Golang客户端

gen-go 上层新建 client.go:

package main

import (
"context"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
"net"
"os"
"thrift_example/gen-go/timerpc"
) func main() {
// 先建立和服务器的连接的socket,再通过socket建立Transport
socket, err := thrift.NewTSocket(net.JoinHostPort("127.0.0.1", "9090"))
if err != nil {
fmt.Println("Error opening socket:", err)
os.Exit(1)
}
transport := thrift.NewTFramedTransport(socket) // 创建二进制协议
protocol := thrift.NewTBinaryProtocolTransport(transport) // 打开Transport,与服务器进行连接
if err := transport.Open(); err != nil {
fmt.Fprintln(os.Stderr, "Error opening socket to "+"localhost"+":"+"9090", err)
os.Exit(1)
}
defer transport.Close() // 接口需要context,以便在长操作时用户可以取消RPC调用
ctx := context.Background() // 使用Mytime服务
MyTimeProtocol := thrift.NewTMultiplexedProtocol(protocol, "mytime") // 创建代理客户端,使用TMultiplexedProtocol访问对应的服务
c := thrift.NewTStandardClient(MyTimeProtocol, MyTimeProtocol) client := timerpc.NewTimeServeClient(c)
res, err := client.GetCurrtentTime(ctx)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(res) // 使用其他服务
// 步骤与上面的相同
// 使用Mytime服务
MyTime2Protocol := thrift.NewTMultiplexedProtocol(protocol, "mytime2")
c2 := thrift.NewTStandardClient(MyTime2Protocol, MyTime2Protocol)
client2 := timerpc.NewTimeServeClient(c2)
res, err = client2.GetCurrtentTime(ctx)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(res)
}

编译并运行:

go build client.go
./client

转载请注明:http://www.lenggirl.com/cap/thrift.html

Thrift RPC Golang、C++ Example的更多相关文章

  1. Golang、Php、Python、Java基于Thrift0.9.1实现跨语言调用

    目录: 一.什么是Thrift? 1) Thrift内部框架一瞥 2) 支持的数据传输格式.数据传输方式和服务模型 3) Thrift IDL 二.Thrift的官方网站在哪里? 三.在哪里下载?需要 ...

  2. thrift rpc通信

    thrift rpc通信 框架 别人的简历: 负责抓取程序的开发和维护,对抓取内容进行数据提取.整理.1.定向数据抓取程序的维护和开发,了解了Sqlite数据库.Thrift服务和多线程的开发调试.2 ...

  3. thrift 的required、optional探究

    原因 经常使用thrift来编写rpc通信,但是对下面两个问题还是有些疑惑 thrift 的required.optional和不写有什么区别 optional不设置isset的话被传输后值? 实验 ...

  4. 转载-- http接口、api接口、RPC接口、RMI、webservice、Restful等概念

     http接口.api接口.RPC接口.RMI.webservice.Restful等概念 收藏 Linux一叶 https://my.oschina.net/heavenly/blog/499661 ...

  5. ubuntu下使用golang、qml与ubuntu sdk开发桌面应用

    ubuntu下使用golang.qml与ubuntu sdk开发桌面应用 (简单示例) 找了很长时间go的gui库,试了gtk,准备试qt的时候发现了这个qml库,试了下很好用. 准备工作 1.Go ...

  6. 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)

    2017年的golang.python.php.c++.c.java.Nodejs性能对比 本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...

  7. 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]

    2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集.   上篇传送门: 2017年的golang.python.p ...

  8. thrift RPC 框架的自我搭建

    安装thrift rpc   安装的系统是Centos 7 未成功的方法 :(原因没找到,但是还是要记录下) 安装依赖库 yum install automake libtool flex bison ...

  9. Thrift RPC实战(三) thrift序列化揭秘

    本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ...

随机推荐

  1. 2018-2019-2 网络对抗技术 20165231 Exp7 网络欺诈防范

    实践内容(3.5分) 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有 (1)简单应用SET工具建立冒名网站 (1分) (2)ettercap DNS spoof ...

  2. final和finally的区别

    final关键字可以用于修饰类,方法,变量.用该关键字修饰类,方法,变量都有不可变的特性. 1)final关键字用于基本数据类型前,就表明该变量就变成了一个常量,在被定义后的赋值不能被修改. 2)fi ...

  3. 【译】Solr in Action 第二章

    2.1 2.2 2.3 基本废话 2.4 基本废话

  4. java JSON的使用和解析

    There is no royal road to learning. 博主:JavaPanda https://www.cnblogs.com/LearnAndGet/p/10009646.html ...

  5. 你的Node应用,对接分布式链路跟踪系统了吗?(一) 原创: 金炳 Node全栈进阶 4天前 戳蓝字「Node全栈进阶」关注我们哦

    你的Node应用,对接分布式链路跟踪系统了吗?(一) 原创: 金炳 Node全栈进阶 4天前 戳蓝字「Node全栈进阶」关注我们哦

  6. linux ubuntu 如何解决warning: no newline at end of file?

    今天写了一段代码, 是在Windows下编辑的, 保存后放在linux系统下编译. gcc和cc都产生以下的警告: a.h:1:2: warning: no newline at end of fil ...

  7. 修改root密码

    Linux 密码的修改,使用passwd 命令修改 命令如下图:sudo passwd root 即可修改成功

  8. css 命名规范参考[转]

    命名空间 另外最好的实践就是当命名你的类名的时候,使用命名空间前缀来进行分类.这些前缀会在你的命名前添加一组字符,但是这个值能立刻标记每一个类的目的,在你看 HTML 或者样式的时候是很需要的.我使用 ...

  9. Cas(02)——部署Cas Server

    部署Cas Server Cas应用都需要有一个Cas Server.Cas Server是基于Java Servlet实现的,其要求部署在Servlet2.4以上版本的Web容器中.在此笔者将其部署 ...

  10. python:一行代码实现局域网共享文件

    其实就是使用python内置的一个模块http server 在python2中是下面这样的 python -m SimpleHTTPServer 80 解释下上面的参数,-m表示让python使用一 ...