项目不完善,使用需谨慎
相关资料
github
homepage / document
目前因为资料还是不是很多,所以最好的学习资料应该就是在github项目主页上挂着的各种实例了~
这里我将代码克隆了下来,用tree命令打印了一下目录:
host@lab:~/scode/pistache$ tree -d -L 2
.
├── build
│ ├── CMakeFiles
│ ├── examples
│ ├── googletest-release-1.7.0
│ ├── src
│ └── tests
├── examples # 官方实例的目录
├── googletest-release-1.7.0
│ ├── build-aux
│ ├── cmake
│ ├── codegear
│ ├── include
│ ├── m4
│ ├── make
│ ├── msvc
│ ├── samples
│ ├── scripts
│ ├── src
│ ├── test
│ └── xcode
├── include
│ └── serializer
├── src
│ ├── client
│ ├── common
│ └── server
└── tests
这里贴出一个实例,顺便注释一下,给大家一个参考:
#include "http.h"
#include "router.h"
#include "endpoint.h"
#include <algorithm>
using namespace std;
using namespace Net;
void printCookies(const Net::Http::Request &req){
auto cookies = req.cookies(); # 获取cookies
std::cout << "Cookies: [" << std::endl;
const std::string indent(4, ' '); # ' ' * 4 = ' '
for(const auto &c: cookies){
std::cout << indent << c.name << " = " << c.value << std::endl;
}
std::cout << "]" << std::endl;
}
namespace Generic{
void handleReady(const Rest::Request &, Http::ResponseWriter response){
response.send(Http::Code::Ok, "1");
}
}
class StatsEndpoint{
public:
StatsEndpoint(Net::Address addr)
: httpEndpoint(std::make_shared<Net::Http::Endpoint>(addr)){}
void init(size_t thr = 2){
auto opts = Net::Http::Endpoint::options()
.threads(thr)
.flags(Net::Tcp::Options::InstallSignalHandler);
httpEndpoint->init(opts);
setupRoutes();
}
void start(){
httpEndpoint->setHandler(router.handler());
httpEndpoint->serve();
}
void shutdown(){
httpEndpoint->shutdown();
}
private:
void setupRoutes(){
using namespace Net::Rest;
Routes::Post(router, "/record/:name/:value?",
Routes::bind(&StatsEndpoint::doRecordMetric, this)); # bind
Routes::Get(router,
"/value/:name", Routes::bind(&StatsEndpoint::doGetMetric, this));
Routes::Get(router,
"/ready", Routes::bind(&Generic::handleReady));
Routes::Get(router,
"/auth", Routes::bind(&StatsEndpoint::doAuth, this));
}
void doRecordMetric(const Rest::Request &request, Net::Http::ResponseWriter response){
auto name = request.param(":name").as<std::string>();
Guard guard(metricsLock); // 加锁
auto it = std::find_if(metrics.begin(),
metrics.end(),
[&](const Metric &metric){
return metric.name() == name;
});
int val = 1;
if(request.hasParam(":value")){
auto value = request.param(":value");
val = value.as<int>();
}
if(it == std::end(metrics)){
metrics.push_back(Metric(std::move(name), val));
response.send(Http::Code::Created, std::to_string(val));
}else{
auto &metric = *it;
metric.incr(val);
response.send(Http::Code::Ok, std::to_string(metric.value()));
}
}
void doGetMetric(const Rest::Request &request, Net::Http::ResponseWriter response){
auto name = request.param(":name").as<std::string>();
Guard guard(metricsLock);
auto it = std::find_if(metrics.begin(), metrics.end(), [&](const Metric &metric){
return metric.name() == name;
});
if(it == std::end(metrics)){
response.send(Http::Code::Not_Found, "Metric does not exist");
}else{
const auto &metric = *it;
response.send(Http::Code::Ok, std::to_string(metric.value()));
}
}
void doAuth(const Rest::Request &request, Net::Http::ResponseWriter response){
printCookies(request);
response.cookies()
.add(Http::Cookie("lang", "en-US"));
response.send(Http::Code::Ok);
}
class Metric{
public:
Metric(std::string name, int initialValue = 1)
: name_(std::move(name)), value_(initialValue){}
int incr(int n = 1){
int old = value_;
value_ += n;
return old;
}
int value() const{
return value_;
}
std::string name() const{
return name_;
}
private:
std::string name_;
int value_;
};
typedef std::mutex Lock;
typedef std::lock_guard<Lock> Guard;
Lock metricsLock;
std::vector<Metric> metrics;
std::shared_ptr<Net::Http::Endpoint> httpEndpoint;
Rest::Router router;
};
int main(int argc, char *argv[]){
Net::Port port(9080);
int thr = 2;
if(argc >= 2){
port = std::stol(argv[1]);
if(argc == 3)
thr = std::stol(argv[2]);
}
Net::Address addr(Net::Ipv4::any(), port);
cout << "Cores = " << hardware_concurrency() << endl;
cout << "Using " << thr << " threads" << endl;
StatsEndpoint stats(addr);
stats.init(thr);
stats.start();
stats.shutdown();
}