<AcWing>-thrift

Basic

一个应用, 包含有 多个 服务, 不同的服务 在不同的服务器上 (也可以在同个服务器)


比如说一个游戏, 一些玩家可以匹配到一起, 然后开始游戏.
(游戏 主服务) (匹配系统 服务)

主服务里, 一个玩家 点击开始匹配, 那么此时: 主服务 会调用 匹配服务的 一个函数add_user函数, 将这个玩家 加入到 匹配系统里

然后比如, 这个玩家 又点击了取消匹配, 就对应为: 主服务 会调用 匹配服务的 remove_user函数, 将这个玩家 从 匹配系统中, 移除掉

比如, 匹配系统, 成功的匹配了一些人, 然后调用 数据库系统 服务save_match函数, 将匹配的结果 存到数据库里, 做一些log记录


thrift, 就是上面的这些函数接口 add_user, remove_user, save_match, 即 服务间的 通信

也就是: A服务器的x进程, 想要调用, B服务器的y进程 AB可以是同个服务器, 这就是thrift

而且, 不同的服务, 使用的语言 可以是不同的! 比如, 游戏服务是 python语言, 匹配系统是 c++语言

thrift是: rpc框架 remote procedure call 远程函数调用


在这里, 比如A 调用了 B的一个函数add_user, 那么: A称为client端, B称为:server端

匹配-服务1

创建 ~/thrift_lession文件夹, 表示, 我们整个项目的工作区, 进入该工作区

vim readme.md   

mkdir game   ' 游戏 服务 '

mkdir match 	' 匹配 服务 '

mkdir thrift   ' 放一些 thrift的函数接口 '

vim match.thrift ' 文件名是match, 说明这是 (针对 match匹配服务的 接口) '

内容如下 这是thrift语法:

namespace cpp match_service    
' 表示, 如果这个thrift去生成一个cpp文件, 则你这里定义的(结构体/函数), 都是在(match_service)的命名空间下的 '

struct User{
    ' 一个结构体 '
    1: i32 id,
    2: string name,
    3: i32 score
}

service Match{
    ' 函数;   match服务, 向外提供的接口 '
    i32 add_user(1: User user, 2: string info),

    i32 remove_user(1: User user, 2: string info),
}

' 进入 ~/thrift_lession/match 文件夹,    即当前是在 匹配服务(也就是一个项目)'

mkdir src      ' 任何一个项目, 最好都要有一个src 存源文件 '

cd src/ 

thrift -r --gen cpp ~/thrift_lesson/thrift/match.thrift  ' 根据之前写的thrift接口, 生成对应的cpp代码 '

此时, 在match/src/, 有一个gen-cpp/的文件夹  ' 这就是上面生成的cpp代码 '
里面有: 'Match.cpp  Match.h  Match_server.skeleton.cpp  match_types.cpp  match_types.h'

mv gen-cpp/ match_server   ' 改个名字.   match_server表示: 这个是服务端的接口. 即是当前match 提供给外界来使用的接口 '

mv match_server/Match_server.skeleton.cpp main.cpp
此时src/里是:
|-- main.cpp    
|-- match_server    
    |-- Match.cpp     
    |-- Match.h     
    |-- match_types.cpp   
    |-- match_types.h

main.cpp

#include "Match.h"

int32_t add_user(const User& user, const std::string& info) {
                 
    // Your implementation goes here                                        
    printf("add_user\n");                                                       
}                                                                           
                                                                            
int32_t remove_user(const User& user, const std::string& info) {
               
    // Your implementation goes here                                        
    printf("remove_user\n");                                                             
}

int main(){
   

	serve();
	return 0;
}

可以发现, 我们的这些接口的实现, 并没有返回值; 手动把函数加上返回值.

由于, 我们将main.cpp, 放到了src下, 自然#include "Match.h"也是错的, 需要加一个match_server/目录

在main函数里, 写一个: ::std::cout<< "test" << ::std::endl;, 注意, 要写上endl
因为, main里有个serve函数, 程序是一直运行的. cout的缓冲区, 刷新到屏幕, 要么是程序结束, 要么你手动的调用endl. 否则, 你看不到cout的输出

先编译下, 让项目正常运行

g++ -c main.cpp ./match_server/*.cpp: 编译, 生成.o
此时, src/下, 有很多的.o

g++ *.o -o main -lthrift (链接dll)

./main 执行


假如你修改了某个cpp, 比如修改了main.cpp. 无需g++ *.cpp -o main
因为, 其他的.o文件 已经有了.

最好是: g++ main.cpp -c, 单独去生成main.o. 然后再: g++ *.o -o main -lthrift


在/src目录下:
git add .
git restore --staged *.o
git restore --staged main

此时, 所有非.o文件 非执行文件, 就都在 暂存区里了 最好只是把一些源文件 放到git里, 把编译结果文件放进去 不太好

游戏-服务1

' 进入 ~/thrift_lession/game 文件夹 '

mkdir src  ' 同样生成src, 存储源文件 '

thrift -r --gen py ../../thrift/match.thrift  ' 根据接口, 生成python代码; 因为, game也需要调用这些接口 '
' 此时, 当前目录下多了: gen-py文件夹 '

mv gen-py/ match_client     ' 改个名字.   表示, 这是客户端要使用的接口 '

tree        ' 这是: src/match_client/ 的目录 '
|-- __init__.py
|-- match
    |-- Match-remote   ' 删除这个文件; 他是提供远程服务的, 而此时是客户端, 不是服务端;  删不删都可以 ' 
    |-- Match.py
    |-- __init__.py
    |-- constants.py
    |-- ttypes.py

client.py

' 在game/src目录下 (此时, 这个目录下 有一个match_client): '

vim client.py

' client.py 如下: '
def main():
    # Make socket
    transport = TSocket.TSocket('127.0.0.1', 9090)

    # Buffering is critical. Raw sockets are very slow
    transport = TTransport.TBufferedTransport(transport)

    # Wrap in a protocol
    protocol = TBinaryProtocol.TBinaryProtocol(transport)

    # Create a client to use the protocol encoder
    client = Match.Client(protocol)

    # Connect!
    transport.open()

    user = User(1, 'wchang', 15000)
    client.add_user( user, "me")    

if __name__ == "__main__":
    main()

此时, 先将我们的match服务里的 之前生成的./main 可执行文件 给运行起来. 他会一直在运行, 在监听

然后, 在这里game 服务里

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值