保安做網(wǎng)站seo排名點擊
目錄
引入cpp-httplib庫
將編譯與運行服務打包
代碼
客戶端用戶路由功能
采用MVC結構進行設計
用戶路由功能
路由功能代碼
引入cpp-httplib庫
對于后端編譯與運行模塊基本已經設計完成,最后用戶是通過網(wǎng)絡傳遞代碼等信息;我們就要將這個模塊引入網(wǎng)絡服務,對于套接字的編寫過程非常麻煩我們可以使用現(xiàn)成HTTP協(xié)議庫。
cpp-httplib 是一個輕量級的、高效的C++ HTTP/HTTPS 客戶端和服務器庫。它由 Hideaki Sone(yhirose)開發(fā),并在 MIT 許可下發(fā)布。該項目的主要目標是提供一種簡單易用的方式,在 C++ 應用程序中實現(xiàn) HTTP 和 HTTPS 功能。
任何版本都可以從網(wǎng)上下載得到,這個庫是一個單頭文件庫,可以直接將這個庫頭文件下載轉移到我們的項目公共模塊中,使用時添加庫頭文件和打開命名空間即可。對于使用這個現(xiàn)成的HTTP庫時我們的gcc編譯器一定要高版本的至少要7版本以上,否則使用低版本的編譯器時對于這個庫可以會在編譯或者運行時報錯;因此我們需要對gcc編譯器進行升級。這里大家從網(wǎng)上自行搜索升級,這里不過多嗶嗶。
將編譯與運行服務打包
通過HTTP協(xié)議服務端收到請求,請求中的請求參數(shù)包含代碼、輸入、時間和空間限制信息,直接提取請求中的響應數(shù)據(jù)交給編譯和運行模塊即可;處理完代碼后,將運行信息作為響應正文交給客戶端即可。
代碼
#include "compile_run.hpp"
#include <jsoncpp/json/json.h>
#include "../comm/httplib.h"
using namespace ns_compiler_and_run;
using namespace httplib;
// 編譯服務隨時可能被多個人請求,必須保證傳遞上來的代碼,形成源文件名稱的時候要具有唯一性,要不然多個用戶之間會影響//
void Usage(std::string proc)
{std::cerr << "Usage : " << "\n\t" << proc << std::endl;
}
int main(int argc, char *argv[2])
{if (argc != 2){Usage(argv[0]);return 1;}// 對外提供一個服務Server svr;svr.Post("/compile_and_run", [](const Request &req, Response &resp){//用戶請求的正文就是我們想要的 json stringstd::string in_json = req.body;std::string out_json;if(!in_json.empty()){//不為空調用編譯和運行服務CompilerAndRun::Start(in_json,&out_json);resp.set_content(out_json,"application/json;charset=utf-8");} });svr.listen("0.0.0.0", atoi(argv[1])); // //httpreturn 0;
}
客戶端用戶路由功能
編譯與運行后端功能模塊編寫完成后,就要對前端模塊進行設計;對于前端的設計簡單來說就是建立一個小型網(wǎng)站,用戶進入網(wǎng)站就是獲取題目列表、編輯代碼、提交判題,這三個主要的模塊。
采用MVC結構進行設計
M: Model,通常是和數(shù)據(jù)交互的模塊,比如,對題庫進行增刪改查(文件版,MySQL)
V: view, 通常是拿到數(shù)據(jù)之后,要進行構建網(wǎng)頁,渲染網(wǎng)頁內容,展示給用戶的(瀏覽器)
C: control, 控制器,就是我們的核心業(yè)務邏輯
用戶路由功能
根據(jù)用戶的需求提供不同的服務,但是也就是只有三個功能:
- 獲取題目列表
- 用戶要根據(jù)題目編號,獲取題目內容
- 提交代碼,使用我們的判題功能(1,每道題的測試用例,2.compile_and_run功能)
路由功能代碼
#include<iostream>
#include"../comm/httplib.h"
using namespace httplib;
int main()
{//用戶請求的路由功能//根據(jù)用戶的需求提供不同的服務//獲取題目列表//用戶要根據(jù)題目編號,獲取題目內容//提交代碼,使用我們的判題功能(1,每道題的測試用例,2.compile_and_run功能)Server svr;svr.Get("/all_question",[](const Request &req,Response &resp){resp.set_content("這是所有的題目列表","text/plain;charset=utf-8");});//svr.Get(R"("/questions/(\d+))",[](const Request &req,Response &resp){//題目編號std::string number = req.matches[1];resp.set_content("這是指定的一道題: "+number , "text/plain;charset=utf-8");});//正則表達式//保證保持原始字符串svr.Get(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;
}
-
正則表達式(regex): 正則表達式是一種用于匹配字符串中字符組合的模式。它們提供了一種靈活的方式來搜索、匹配和操作文本。在這個代碼中,正則表達式被用于匹配請求的URL路徑中特定的模式。
-
R前綴: 在C++中,R前綴用于創(chuàng)建原始字符串字面量。原始字符串字面量將反斜杠(\)視為字面字符而不是轉義字符。這在處理正則表達式或任何其他字符串時非常有用,你不想解釋轉義序列時可以使用它。
解釋:
- 在第二和第三個路由定義中,正則表達式被用在原始字符串字面量(前綴為
R
)中,用于定義動態(tài)路由,匹配包含數(shù)字模式的URL。 - 在第二個路由(
/questions/(\d+)
)中,模式是尋找包含/questions/
后跟一個或多個數(shù)字的URL。括號(\d+)
捕獲數(shù)字作為一個組,以備后用。 - 在第三個路由(
/judge/(\d+)
)中,模式類似,但匹配包含/judge/
后跟一個或多個數(shù)字的URL。 - 在與每個路由關聯(lián)的lambda函數(shù)內部,從URL中捕獲的數(shù)字使用
req.matches[1]
進行檢索,其中req.matches
保存了正則表達式捕獲的匹配組。然后使用這些數(shù)字來提供特定路由的響應。
今天對項目網(wǎng)絡庫引入和用戶路由功能的分享到這就結束了,希望大家讀完后有很大的收獲,也可以在評論區(qū)點評文章中的內容和分享自己的看法;個人主頁還有很多精彩的內容。您三連的支持就是我前進的動力,感謝大家的支持!!!?