在線oj之server模塊

oj_server.cpp模塊是整個在線oj項目與外界溝通的橋樑,負責項目後臺與外界的通信。在這個模塊中使用了github上一個http開源庫(上一篇博客我提到過),模板填充技術以及Json數據格式,裏面有些可能看不懂,後面的博客我會詳細介紹。

Server:httplib中的一個Server類
Get:Server中的Get請求方法
Post:Server中的Post方法
set_content:httplib中定義的響應接口
listen:Server中的監聽方法

    //有興趣可以自己看源代碼
  Server &Get(const char *pattern, Handler handler);
  Server &Post(const char *pattern, Handler handler);
  using Handler = std::function<void(const Request &, Response &)>;
  void set_content(std::string s, const char *content_type);
  bool listen(const char *host, int port, int socket_flags = 0);

OjModel:試題信息模塊的一個類,裏面封裝了獲取試題信息的方法
OjView:頁面渲染模塊,裏面封裝了用於將獲取到的信息渲染到網頁的方法
LOG:日誌模塊下一個打印消息的方法
Compiler:編譯模塊中的一個類

主頁面效果,很low
在這裏插入圖片描述

#include "httplib.h"
#include "oj_model.hpp"
#include "oj_view.hpp"
#include "oj_log.hpp"
#include "compile.hpp"


int main()
{
    //httplib的時候,需要使用httplib使用的命名空間
    using namespace httplib;

    Server svr;

    OjModel oj_model;
    //獲取試題信息,信息來源於文件
    svr.Get("/all_questions", [&oj_model](const Request& req, Response& resp){
            std::vector<Question> ques;
            oj_model.GetAllQuestions(&ques);
            std::string html;
            //想使用模板技術去填充html頁面
            OjView::ExpandAllQuestionsHtml(&html, ques);
            resp.set_content(html, "text/html; charset=UTF-8");
            });

    //正則表達式
    // \b 單詞的分界
    // *:匹配任意字符串
    // \d:匹配一個數字
    // (): 分組應用
    // 源碼轉義:特殊字符按照特殊字符字面源碼編譯 R"(str)“
  svr.Get(R"(/question/(\d+))", [&oj_model](const Request& req, Response& resp){
      //1.去試題模塊查找對應題號的具體題目信息
      //  map當中(序號 名稱 題目地址 難度)

      std::string desc;
      std::string header;
      //從querystr中獲取id
      LOG(INFO, "req.matches") << req.matches[0] << ":" << req.matches[1] << std::endl;
      //  2. 在題目地址的路徑下去加載單個題目的描述信息
      struct Question ques;
      oj_model.GetOneQuestion(req.matches[1].str(), &desc, &header, &ques);
      //3.組織,返回給瀏覽器
      std::string html;
      OjView::ExpandOneQuestion(ques, desc, header, &html);
      resp.set_content(html, "text/html; charset=UTF-8");
  });

  svr.Post(R"(/question/(\d+))", [&oj_model](const Request& req, Response& resp){
          //1.從正文當中提取出來提交的內容,主要是提取code字段的內容
          // 提交的內容當中有url編碼,需要對提交內容解碼
          std::unordered_map<std::string, std::string> pram;
          UrlUtil::PraseBody(req.body, &pram);
          //  2. 編譯&&運行
          std::string code;
          oj_model.SplitingCode(pram["code"], req.matches[1].str(), &code);
          Json::Value req_json;
          req_json["code"] = code;
          Json::Value resp_json;
          Compiler::CompilerAndRun(req_json, &resp_json);
          //  3.構造響應,json
          const std::string errorno = resp_json["errorno"].asString();
          const std::string reason = resp_json["reason"].asString();
          const std::string stdout_reason = resp_json["stdout"].asString();
          std::string html;
          OjView::ExpandReason(errorno, reason, stdout_reason, &html);
          resp.set_content(html, "text/html; charset=UTF-8");
          });
  LOG(INFO, "Listen in 0.0.0.0:20000");
  LOG(INFO, "Server ready");
  svr.listen("0.0.0.0", 20000);
  return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章