将cr打包成网络服务
compile_server.cc
#include "compile_run.hpp"
#include "../comm/httplib.h"
using namespace ns_compile_and_run;
using namespace httplib;
//编译服务随时可能被多个人请求,必须保证传递上来的code,形成源文件名称的时候,要具有
//唯一性,要不然多个用户之间会互相影响
int main()
{
Server svr;
svr.Get("/hello",[](const Request &req, Response &resp){
// 用来进行基本测试
resp.set_content("hello httplib,你好 httplib!", "text/plain;charset=utf-8");
});
svr.Post("/compile_and_run", [](const Request &req, Response &resp){
// 用户请求的服务正文是我们想要的json string
std::string in_json = req.body;
std::string out_json;
if(!in_json.empty()){
CompileAndRun::Start(in_json, &out_json);
resp.set_content(out_json, "application/json;charset=utf-8");
}
});
//svr.set_base_dir("./wwwroot");
svr.listen("0.0.0.0", 8080); //启动http服务
//提供的编译服务,打包形成一个网络服务
//cpp-httplib
// in_json: {"code": "#include...", "input": "","cpu_limit":1, "mem_limit":10240}
// out_json: {"status":"0", "reason":"","stdout":"","stderr":"",}
// 通过http 让client 给我们 上传一个json string
// 下面的工作,充当客户端请求的json串
std::string in_json;
Json::Value in_value;
//R"()", raw string
in_value["code"] = R"(#include<iostream>
int main(){
std::cout << "你可以看见我了" << std::endl;
return 0;
})";
in_value["input"] = "";
in_value["cpu_limit"] = 1;
in_value["mem_limit"] = 10240*3;
Json::FastWriter writer;
in_json = writer.write(in_value);
std::cout << in_json << std::endl;
//这个是将来给客户端返回的json串
std::string out_json;
CompileAndRun::Start(in_json, &out_json);
std::cout << out_json << std::endl;
return 0;
}
使用postman进行测试
安装postman
Download Postman | Get Started for Free
填入对应内容
地址是http://47.94.228.92:8080/compile_and_run
选择POST,raw和JSON
{
"code" : "#include <iostream>\nint main(){std::cout << \"你好,编译服务!\" << std::endl;}",
"input" : "",
"cpu_limit" : 1,
"mem_limit" : 50000
}
编译运行成功
{
"code" : "#include <iostream>\nint main(){while(1);std::cout << \"你好,编译服务!\" << std::endl;}",
"input" : "",
"cpu_limit" : 1,
"mem_limit" : 50000
}
#include "compile_run.hpp"
#include "../comm/httplib.h"
using namespace ns_compile_and_run;
using namespace httplib;
void Usage(std::string proc)
{
std::cerr << "Usage: " << "\n\t" << proc << " port" << std::endl;
}
//编译服务随时可能被多个人请求,必须保证传递上来的code,形成源文件名称的时候,要具有
//唯一性,要不然多个用户之间会互相影响
//./compile_server port
int main(int argc, char *argv[])
{
if(argc != 2){
Usage(argv[0]);
return 1;
}
Server svr;
svr.Get("/hello",[](const Request &req, Response &resp){
// 用来进行基本测试
resp.set_content("hello httplib,你好 httplib!", "text/plain;charset=utf-8");
});
svr.Post("/compile_and_run", [](const Request &req, Response &resp){
// 用户请求的服务正文是我们想要的json string
std::string in_json = req.body;
std::string out_json;
if(!in_json.empty()){
CompileAndRun::Start(in_json, &out_json);
resp.set_content(out_json, "application/json;charset=utf-8");
}
});
//svr.set_base_dir("./wwwroot");
svr.listen("0.0.0.0", atoi(argv[1])); //启动http服务
//提供的编译服务,打包形成一个网络服务
//cpp-httplib
// in_json: {"code": "#include...", "input": "","cpu_limit":1, "mem_limit":10240}
// out_json: {"status":"0", "reason":"","stdout":"","stderr":"",}
// 通过http 让client 给我们 上传一个json string
// 下面的工作,充当客户端请求的json串
std::string in_json;
Json::Value in_value;
//R"()", raw string
in_value["code"] = R"(#include<iostream>
int main(){
std::cout << "你可以看见我了" << std::endl;
return 0;
})";
in_value["input"] = "";
in_value["cpu_limit"] = 1;
in_value["mem_limit"] = 10240*3;
Json::FastWriter writer;
in_json = writer.write(in_value);
std::cout << in_json << std::endl;
//这个是将来给客户端返回的json串
std::string out_json;
CompileAndRun::Start(in_json, &out_json);
std::cout << out_json << std::endl;
return 0;
}
请求时候直接输入端口号
./compile_server 8080
这样输入不同的端口号进行申请,就会有多个编译服务
oj_server准备工作
基于MVC结构的oj服务设计
本质:建立一个小型网站
- 获取首页,用题目列表充当
- 编辑区域页面
- 提交判题功能(编译并运行)
M:Model,通常是和数据交互的模块,比如,对题库进行增删改查(文件版,MySQL)
V:view, 通常是拿到数据之后,要进行构建网页,渲染网页内容,展示给用户的(浏览器)
C:control, 控制器,就是我们的核心业务逻辑
makefile
oj_server:oj_server.cc
g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
rm -f oj_server
编写服务路由功能
oj_server.cc
using namespace httplib;
int main()
{
//用户请求的服务路由功能
Server svr;
// 获取所有的题目列表
// 用户要根据题目编号,获取题目的内容
// 用户提交代码,使用我们的判题功能(1. 每道题的测试用例 2. compile_and_run)
svr.listen("0.0.0.0", 8080);
return 0;
}
oj_server.cc
#include <iostream>
#include "../comm/httplib.h"
using namespace httplib;
int main()
{
//用户请求的服务路由功能
Server svr;
// 获取所有的题目列表
svr.Get("/all_questions", [](const Request &req, Response &resp){
resp.set_content("这是所有题目的列表", "text/plain; charset=utf-8");
});
// 用户要根据题目编号,获取题目的内容
// /question/100 -> 正则匹配
// R"()", 原始字符串raw string,保持字符串内容的原貌,不用做相关的转义
svr.Get(R"(/question/(\d+))", [](const Request &req, Response &resp){
std::string number = req.matches[1];
resp.set_content("这是指定的一道题:" + number, "text/plain; charset=utf-8");
});
// 用户提交代码,使用我们的判题功能(1. 每道题的测试用例 2. compile_and_run)
svr.Post(R"(/judge/(\d+))", [](const Request &req, Response &resp){
std::string number = req.matches[1];
resp.set_content("指定题目的判题: " + number, "text/plain; charset=utf-8");
});
svr.listen("0.0.0.0", 8080);
return 0;
}
makefile
oj_server:oj_server.cc
g++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:
rm -f oj_server
编译运行
加入主页信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>这是我的个人OJ系统</title>
</head>
<h1>欢迎来到我的OJ</h1>
<p>这是我个人独立开发的在线OJ平台</p>
<body>
</body>
</html>
在oj_server.cc中加入svr.set_base_dir("./wwwroot");
#include <iostream>
#include "../comm/httplib.h"
using namespace httplib;
int main()
{
//用户请求的服务路由功能
Server svr;
// 获取所有的题目列表
svr.Get("/all_questions", [](const Request &req, Response &resp){
resp.set_content("这是所有题目的列表", "text/plain; charset=utf-8");
});
// 用户要根据题目编号,获取题目的内容
// /question/100 -> 正则匹配
// R"()", 原始字符串raw string,保持字符串内容的原貌,不用做相关的转义
svr.Get(R"(/question/(\d+))", [](const Request &req, Response &resp){
std::string number = req.matches[1];
resp.set_content("这是指定的一道题:" + number, "text/plain; charset=utf-8");
});
// 用户提交代码,使用我们的判题功能(1. 每道题的测试用例 2. compile_and_run)
svr.Post(R"(/judge/(\d+))", [](const Request &req, Response &resp){
std::string number = req.matches[1];
resp.set_content("指定题目的判题: " + number, "text/plain; charset=utf-8");
});
svr.set_base_dir("./wwwroot");
svr.listen("0.0.0.0", 8080);
return 0;
}