17 Star 74 Fork 35

Plato / ServiceBox

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README-cpp_service.md 5.22 KB
一键复制 编辑 原始数据 按行查看 历史

编写C++语言服务

C++服务已DLL/SO方式进行部署, 这个DLL/SO称之为bundle(这个名称借鉴于OSGi, 但完全不能类比), 每一个bundle内含有对一个服务接口的实现。

编写服务定义

假设有一个服务定义, 定义在文件名为game.idl(接口描述文件请参考:IDL服务定义)内,

service dynamic MyFirstService single {
	void HelloWorld()
}

这是一个名为MyFirstService 服务,里面有一个名为HelloWorld的方法。自己定义的game.idl需要存放于src/repo/example目录内:

example
└── game.idl

生成c++服务

如果没有初始化过repo的话,需要先执行init.py脚本,来进行repo仓库得初始化。

在src/repo目录下运行:

python repo.py -t cpp -a example/game.idl					// 添加idl文件

这个时候repo会产生一些文件:

repo
├── bin													// 存放第三方库生成的二进制以及脚本
├── example												// 存放idl的地方
├── lib													// 存放服务器生成.a以及.so的地方
│   ├── proxy
│   ├── root
│   └── stub
├── src													// 所有代码生成的文件都在这里 中间目录
│   ├── game
│   ├── idl
│   ├── include
│   ├── proxy
│   └── stub
├── thirdparty											// 第三方库
├── tmp													// 依赖的其他的rpc库
│   ├── rpc-backend-cpp
│   ├── rpc-frontend
│   └── rpc-repo
└── usr													// 你需要关心的文件目录
    ├── impl											// 服务的实现代码
    │   └── game			
    │       └── MyFirstService							// MyFirstService服务相关的文件
    │           ├── CMakeLists.txt						// 如果服务器需要其他的依赖 可以在这边增加
    │           ├── game.service.MyFirstService.cpp		// 用户需要实现的文件
    │           └── game.service.MyFirstService.impl.h
    └── lua_template									// lua服务器相关的摸板

功能实现

这边会产生三个关键文件,这写文件是需要用户关心的:CMakeLists.txt demoscene.service.Scene.cpp demoscene.service.Scene.impl.h

  • CMakeList.txt 编写的规则可以参考 自定义CMake
  • demoscene.service.Scene.cpp 实现文件
// Machine generated code

#include <utility>
#include "rpc_singleton.h"
#include "object_pool.h"
#include "rpc_root.h"
#include "game.service.MyFirstService.impl.h"
#include <iostream>

MyFirstServiceImpl::MyFirstServiceImpl() {}
MyFirstServiceImpl::~MyFirstServiceImpl() {}
bool MyFirstServiceImpl::onAfterFork(rpc::Rpc* rpc) { return true; }
bool MyFirstServiceImpl::onBeforeDestory(rpc::Rpc* rpc) { return true; }
void MyFirstServiceImpl::onTick(std::time_t ms) { return; }
void MyFirstServiceImpl::onServiceCall(rpc::StubCallPtr callPtr) { return; }
void MyFirstServiceImpl::HelloWorld(rpc::StubCallPtr call) {
	// 打印 “Hello World!”
    std::cout << "Hello World!" << std::endl;
}
  • game.service.MyFirstService.impl.h 头文件
 #pragma once

#include "game.service.MyFirstService.h"

class MyFirstServiceImpl : public MyFirstService {
public:
//implementation->
    MyFirstServiceImpl();
    virtual ~MyFirstServiceImpl();
    virtual bool onAfterFork(rpc::Rpc* rpc) override;
    virtual bool onBeforeDestory(rpc::Rpc* rpc) override;
    virtual void onTick(std::time_t ms) override;
    virtual void onServiceCall(rpc::StubCallPtr callPtr) override;
    virtual void HelloWorld(rpc::StubCallPtr call) override;
//implementation<-
};

生成好文件之后,继续在src/repo目录下运行:

python repo.py -t cpp -b game								// 生成工程并且编译服务

结果会产生:

repo
├── tmp													// 依赖的其他的rpc库
│	└── game
│       ├── proxy
│    	│	└── MyFirstService
│       └── stub
│      		└── MyFirstService							// windows的情况下这个目录会有相对应工程文件│
└── lib													// lib当中会产生相对应的.a与.so
    ├── game
    │   └── libgame.a
    ├── proxy
    │   └── game
    │       └── MyFirstService
    │           └── libMyFirstService_proxy.a
    └── stub
        ├── demodata
        └── game
            └── MyFirstService
                ├── libMyFirstService.so
                └── libMyFirstService_stub.a

修改并重新生成服务

打开src/repo/idl/game.idl,修改完毕后在src/repo下运行:

python repo.py -t cpp -u game:MyFirstService
python repo.py -t cpp -b game:MyFirstService

简易测试

service-box 提供了一个简易测试:mock

进入到src/repo/bin/Debug 目录下:

// 分别开两个窗口来 `先后` 执行
myfirstservice_server.exe -h 127.0.0.1 -p 1234
myfirstservice_proxy.exe -h 127.0.0.1 -p 1234

// 在server的窗口你会看见
accepted
Hello World!

// 在proxy的窗口你会看见
[MyFirstService] connected
C++
1
https://gitee.com/dennis-kk/service-box.git
git@gitee.com:dennis-kk/service-box.git
dennis-kk
service-box
ServiceBox
master

搜索帮助