2019-03-21 16:03:24 +08:00
|
|
|
#include <rpc_server.h>
|
|
|
|
|
using namespace rest_rpc;
|
|
|
|
|
using namespace rpc_service;
|
2019-03-28 12:58:18 +08:00
|
|
|
#include <fstream>
|
2019-04-04 16:55:48 +08:00
|
|
|
|
|
|
|
|
#include "qps.h"
|
|
|
|
|
|
2019-03-21 16:03:24 +08:00
|
|
|
struct dummy{
|
2019-05-17 14:56:44 +08:00
|
|
|
int add(rpc_conn conn, int a, int b) { return a + b; }
|
2019-03-21 16:03:24 +08:00
|
|
|
};
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
std::string translate(rpc_conn conn, const std::string& orignal) {
|
2019-03-21 16:03:24 +08:00
|
|
|
std::string temp = orignal;
|
|
|
|
|
for (auto& c : temp) {
|
|
|
|
|
c = std::toupper(c);
|
|
|
|
|
}
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
void hello(rpc_conn conn, const std::string& str) {
|
2019-03-21 16:03:24 +08:00
|
|
|
std::cout << "hello " << str << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct person {
|
|
|
|
|
int id;
|
|
|
|
|
std::string name;
|
|
|
|
|
int age;
|
|
|
|
|
|
|
|
|
|
MSGPACK_DEFINE(id, name, age);
|
|
|
|
|
};
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
std::string get_person_name(rpc_conn conn, const person& p) {
|
2019-03-21 16:03:24 +08:00
|
|
|
return p.name;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
person get_person(rpc_conn conn) {
|
2019-03-21 16:03:24 +08:00
|
|
|
return { 1, "tom", 20 };
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
void upload(rpc_conn conn, const std::string& filename, const std::string& content) {
|
2019-03-28 12:58:18 +08:00
|
|
|
std::cout << content.size() << std::endl;
|
|
|
|
|
std::ofstream file(filename, std::ios::binary);
|
|
|
|
|
file.write(content.data(), content.size());
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
std::string download(rpc_conn conn, const std::string& filename) {
|
2019-03-28 12:58:18 +08:00
|
|
|
std::ifstream file(filename, std::ios::binary);
|
|
|
|
|
if (!file) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file.seekg(0, std::ios::end);
|
|
|
|
|
size_t file_len = file.tellg();
|
|
|
|
|
file.seekg(0, std::ios::beg);
|
|
|
|
|
std::string content;
|
|
|
|
|
content.resize(file_len);
|
|
|
|
|
file.read(&content[0], file_len);
|
|
|
|
|
std::cout << file_len << std::endl;
|
|
|
|
|
|
|
|
|
|
return content;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-04 16:55:48 +08:00
|
|
|
qps g_qps;
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
std::string get_name(rpc_conn conn, const person& p) {
|
2019-04-04 16:55:48 +08:00
|
|
|
g_qps.increase();
|
|
|
|
|
return p.name;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 14:56:44 +08:00
|
|
|
//if you want to response later, you can use async model, you can control when to response
|
|
|
|
|
void async_echo(rpc_conn conn, const std::string& src) {
|
2019-05-21 16:40:28 +08:00
|
|
|
auto req_id = conn.lock()->request_id();//note: you need keep the request id at that time, and pass it into the async thread
|
|
|
|
|
|
|
|
|
|
std::thread thd([conn, req_id, src] {
|
2019-05-17 14:56:44 +08:00
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
|
|
|
auto conn_sp = conn.lock();
|
|
|
|
|
if (conn_sp) {
|
2019-05-21 16:40:28 +08:00
|
|
|
conn_sp->pack_and_response(req_id, std::move(src));
|
2019-05-17 14:56:44 +08:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
thd.detach();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string echo(rpc_conn conn, const std::string& src) {
|
|
|
|
|
return src;
|
2019-05-09 10:25:58 +08:00
|
|
|
}
|
|
|
|
|
|
2019-06-04 08:56:41 +08:00
|
|
|
int get_int(rpc_conn conn, int val) {
|
|
|
|
|
return val;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-23 19:58:17 +08:00
|
|
|
struct notifier {
|
|
|
|
|
public:
|
|
|
|
|
notifier() {
|
|
|
|
|
std::thread thd([this] {
|
|
|
|
|
while (!stop_) {
|
|
|
|
|
if (has_subs_) {
|
|
|
|
|
notify("this a notification from the server");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
thd.detach();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~notifier() {
|
|
|
|
|
stop_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sub(rpc_conn conn) {
|
|
|
|
|
if (!has_subs_) {
|
|
|
|
|
has_subs_ = true;
|
|
|
|
|
}
|
|
|
|
|
auto req_id = conn.lock()->request_id();
|
|
|
|
|
std::unique_lock<std::mutex> lock(mtx_);
|
|
|
|
|
subs_.emplace_back(conn, req_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void notify(const std::string& result) {
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> lock(mtx_);
|
|
|
|
|
for (auto& pair : subs_) {
|
|
|
|
|
auto sp_conn = pair.first.lock();
|
|
|
|
|
if (sp_conn) {
|
|
|
|
|
sp_conn->pack_and_response(pair.second, result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
subs_.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
has_subs_ = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<std::pair<rpc_conn, uint64_t>> subs_;
|
|
|
|
|
std::mutex mtx_;
|
|
|
|
|
std::atomic_bool has_subs_ = { false };
|
|
|
|
|
bool stop_ = false;
|
|
|
|
|
};
|
|
|
|
|
|
2019-03-21 16:03:24 +08:00
|
|
|
int main() {
|
2019-04-10 13:48:35 +08:00
|
|
|
rpc_server server(9000, std::thread::hardware_concurrency());
|
2019-03-21 16:03:24 +08:00
|
|
|
|
|
|
|
|
dummy d;
|
|
|
|
|
server.register_handler("add", &dummy::add, &d);
|
|
|
|
|
server.register_handler("translate", translate);
|
|
|
|
|
server.register_handler("hello", hello);
|
|
|
|
|
server.register_handler("get_person_name", get_person_name);
|
|
|
|
|
server.register_handler("get_person", get_person);
|
2019-03-28 12:58:18 +08:00
|
|
|
server.register_handler("upload", upload);
|
|
|
|
|
server.register_handler("download", download);
|
2019-04-04 16:55:48 +08:00
|
|
|
server.register_handler("get_name", get_name);
|
2019-05-24 09:30:01 +08:00
|
|
|
server.register_handler<Async>("async_echo", async_echo);
|
2019-05-17 14:56:44 +08:00
|
|
|
server.register_handler("echo", echo);
|
2019-06-04 08:56:41 +08:00
|
|
|
server.register_handler("get_int", get_int);
|
2019-03-21 16:03:24 +08:00
|
|
|
|
2019-05-23 19:58:17 +08:00
|
|
|
notifier n;
|
2019-05-24 09:30:01 +08:00
|
|
|
server.register_handler<Async>("sub", ¬ifier::sub, &n);
|
2019-05-23 19:58:17 +08:00
|
|
|
|
2019-03-21 16:03:24 +08:00
|
|
|
server.run();
|
|
|
|
|
|
|
|
|
|
std::string str;
|
|
|
|
|
std::cin >> str;
|
|
|
|
|
}
|