国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...

這篇具有很好參考價值的文章主要介紹了[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux


在前四篇文章中, 我們實現(xiàn)了從文檔文件的清理 到 搜索的所有內(nèi)容:

  1. 項目背景: ??[C++項目] Boost文檔 站內(nèi)搜索引擎(1): 項目背景介紹、相關(guān)技術(shù)棧、相關(guān)概念介紹…
  2. 文檔解析、處理模塊parser的實現(xiàn): ??[C++項目] Boost文檔 站內(nèi)搜索引擎(2): 文檔文本解析模塊parser的實現(xiàn)、如何對文檔文件去標(biāo)簽、如何獲取文檔標(biāo)題…
  3. 文檔 正排索引與倒排索引 建立的接口的實現(xiàn): ??[C++項目] Boost文檔 站內(nèi)搜索引擎(3): 建立文檔及其關(guān)鍵字的正排 倒排索引、jieba庫的安裝與使用…
  4. 文檔的 搜索功能 接口的實現(xiàn): ??[C++項目] Boost文檔 站內(nèi)搜索引擎(4): 實現(xiàn)搜索的相關(guān)接口、線程安全的單例index接口、cppjieba分詞庫的使用…
  5. 建議先閱讀上面四篇文章

后端的主要功能接口完成之后, 就可以結(jié)合網(wǎng)絡(luò)將其設(shè)計為服務(wù)器 然后部署到網(wǎng)絡(luò)上了

網(wǎng)絡(luò)服務(wù)

我們使用cpphttplib庫 實現(xiàn)搜索引擎服務(wù)器. 所以要先安裝cpphttplib

cpphttplib

使用cpphttplib時, gcc版本不能太低. 而CentOS 7默認(rèn)的版本是4.8.5, 太低了. 所以安裝使用cpphttplib之前, 要先升級gcc到至少7.x以上

gcc升級

我們將gcc升級到8.3.1. 非常的簡單, 只需要一共6條指令 就可以完成:

# 安裝 centos-release-scl
sudo yum install centos-release-scl
# 安裝 devtoolset-8-gcc* (gcc8相關(guān)軟件包)
sudo yum install devtoolset-8-gcc*

# 安裝完成, 需要建立軟連接
mv /usr/bin/gcc /usr/bin/gcc-4.8.5
ln -s /opt/rh/devtoolset-8/root/bin/gcc /usr/bin/gcc
mv /usr/bin/g++ /usr/bin/g++-4.8.5
ln -s /opt/rh/devtoolset-8/root/bin/g++ /usr/bin/g++

然后就可以看到:

? gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-8/root/usr --mandir=/opt/rh/devtoolset-8/root/usr/share/man --infodir=/opt/rh/devtoolset-8/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-8.3.1-20190311/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)
? g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-8/root/usr --mandir=/opt/rh/devtoolset-8/root/usr/share/man --infodir=/opt/rh/devtoolset-8/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-8.3.1-20190311/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

安裝cpphttplib

cpphttplib庫的安裝非常簡單, 因為整個庫中 只需要用到一個httplib.h的頭文件.

但是, 我們需要選擇版本安裝, 不能直接安裝最新版的. 因為gcc編譯器版本不匹配的話 可能 會出現(xiàn)無法編譯或運行時錯誤的情況

這里推薦0.7.16的版本: https://github.com/yhirose/cpp-httplib/tree/v0.7.16

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

可以直接獲取此版本的源碼:

? wget https://codeload.github.com/yhirose/cpp-httplib/zip/refs/tags/v0.7.16

然后解壓出來, 將httplib.h拷貝到項目目錄下:

? wget https://codeload.github.com/yhirose/cpp-httplib/zip/refs/tags/v0.7.16
--2023-08-08 14:24:23--  https://codeload.github.com/yhirose/cpp-httplib/zip/refs/tags/v0.7.16
Resolving codeload.github.com (codeload.github.com)... 20.205.243.165
Connecting to codeload.github.com (codeload.github.com)|20.205.243.165|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘v0.7.16’

    [   <=>                                                                                                                                     ] 586,948     1.10MB/s   in 0.5s

2023-08-08 14:24:25 (1.10 MB/s) - ‘v0.7.16’ saved [586948]

? unzip v0.7.16
Archive:  v0.7.16
    ... 解壓過程
 extracting: cpp-httplib-0.7.16/test/www3/dir/test.html
? ll
total 588K
drwxr-xr-x 6 July July 4.0K Nov 30  2020 cpp-httplib-0.7.16
drwxr-xr-x 9 July July 4.0K Aug  7 00:16 cppjieba
drwxr-xr-x 6 July July 4.0K Aug  8 13:52 gitHub
-rw-r--r-- 1 July July 574K Aug  8 14:24 v0.7.16

# 將httplib.h 拷貝到項目目錄下:
cp cpp-httplib-0.7.16/httplib.h gitHub/Boost-Doc-Searcher/.

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

這就算在項目中安裝成功了

cpphttplib的簡單使用

關(guān)于cpphttplib的使用, Github文檔有簡單的使用介紹

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

直接使用這段代碼 可以實現(xiàn)怎么樣的結(jié)果呢?

#include <iostream>
#include <pthread.h>
#include "httplib.h"

// 由于庫中使用了線程相關(guān)接口, 所以要包含線程頭文件

int main() {
	httplib::Server svr;

	svr.Get("/hi", [](const httplib::Request&, httplib::Response& res) {
		res.set_content("Hello World!", "text/plain");
	});

	svr.listen("0.0.0.0", 8080);

	return 0;
}

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

直接訪問根url, 沒有任何響應(yīng). 但是如果我們在url之后添加/hi. 就能看到Hello World!的字樣.

這就是我們設(shè)定的 申請/hi資源時, 會響應(yīng)的內(nèi)容:

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

httplib::Server::Get()是用來處理HTTPGET方法的接口.

  1. 第一個參數(shù), 用來指定處理 申請某內(nèi)容的請求.

    如果傳入/hi, 就會處理 請求的urlwwwRoot/hi的請求. 如果傳入/index.html, 就會處理 請求的urlwwwRoot/hi的請求

    wwwRoot表示web根目錄, 沒有設(shè)置 即為服務(wù)器運行路徑

  2. 第二個參數(shù), 是一個回調(diào)函數(shù) 用來 接收請求 對請求進(jìn)行處理, 并響應(yīng)

    此回調(diào)函數(shù)的第一個參數(shù) 就是用來接收請求的.

    第二個參數(shù), 可以看作一個輸出型參數(shù). 是用來填充響應(yīng)的

    在例子中, 使用httplib::Response::set_content(), 接口設(shè)置響應(yīng)正文以及相應(yīng)的類型

最后監(jiān)聽指定端口, 就可以通過ip:port的形式訪問服務(wù)器.

項目網(wǎng)絡(luò)服務(wù) **

了解了cpphttplib的最基本使用. 就可以為項目創(chuàng)建網(wǎng)絡(luò)服務(wù)了

但是, 創(chuàng)建網(wǎng)絡(luò)服務(wù)之前. 可以先了解一下 搜索引擎的搜索結(jié)果是怎么出現(xiàn)的?

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

當(dāng)我們搜索時, 會申請/search這個服務(wù). 并攜帶了?q=Searcher這個key(q)=value(Searcher)屬性.

然后, 就會將搜索結(jié)果顯示出來.

cpphttplib提供了檢索url中是否存在key的接口, 并且可以通過key獲取value值的接口, 所以我們就可以這樣來向頁面設(shè)置內(nèi)容:

svr.Get("/search", [](const httplib::Request& request, httplib::Response& response) {
    if (!request.has_param("word")) {
        // url中沒有 word 鍵值
        // set_content() 第一個參數(shù)是設(shè)置正文內(nèi)容, 第二個參數(shù)是 正文內(nèi)容類型等屬性
        response.set_content("請輸入內(nèi)容后搜索", "text/plain; charset=utf-8");
    }
});

然后運行服務(wù)器并訪問/search:

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

當(dāng)url中沒有keyword的鍵值時, 就會顯示 請輸入內(nèi)容后搜索

如果有keyword的鍵值, 因為我們沒有做任何操作, 所以不會有任何內(nèi)容:

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

除了判斷是否存在key, 還可以通過接口獲得對應(yīng)的value:

svr.Get("/search", [](const httplib::Request& request, httplib::Response& response) {
		if (!request.has_param("word")) {
			// url中沒有 word 鍵值
			// set_content() 第一個參數(shù)是設(shè)置正文內(nèi)容, 第二個參數(shù)是 正文內(nèi)容類型等屬性
			response.set_content("請輸入內(nèi)容后搜索", "text/plain; charset=utf-8");
		}
		std::string word = request.get_param_value("word");
		response.set_content(word, "text/plain; charset=utf-8");
});

此時, 再攜帶key=value鍵對:

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

就獲取到了value的內(nèi)容, 并設(shè)置為了響應(yīng)內(nèi)容.

既然可以獲取url中的鍵值, 那么 就可以實現(xiàn)根據(jù)鍵值調(diào)用searcher::search()接口, 搜索相關(guān)文檔:

#include <iostream>
#include <pthread.h>
#include "util.hpp"
#include "searcher.hpp"
#include "httplib.h"

const std::string& input = "./data/output/raw";

int main() {
    ns_searcher::searcher searcher;
    searcher.initSearcher(input);

    httplib::Server svr;

    svr.Get("/s", [&searcher](const httplib::Request& request, httplib::Response& response {
        if (!request.has_param("word")) {
            // url中沒有 word 鍵值
            // set_content() 第一個參數(shù)是設(shè)置正文內(nèi)容, 第二個參數(shù)是 正文內(nèi)容類型等屬性
            response.set_content("請輸入內(nèi)容后搜索", "text/plain; charset=utf-8");
        }
        std::string searchContent = request.get_param_value("word");
        std::cout << "User search:: " << searchContent << std::endl;

        std::string searchJsonResult;
        searcher.search(searchContent, &searchJsonResult);
        // 搜獲取到搜索結(jié)果之后 設(shè)置相應(yīng)內(nèi)容
        response.set_content(searchJsonResult, "application/json");
    });

    std::cout << "服務(wù)器啟動成功..." << std::endl;
    svr.listen("0.0.0.0", 8080);

    return 0;
}

編譯代碼 g++ httpServer.cc -lpthread -ljsoncpp

運行程序. 建立索引 等待服務(wù)器開啟成功之后:

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

直接在url添加鍵值 就可以看到直接的搜索結(jié)果.

至此, 網(wǎng)絡(luò)服務(wù)的編寫就完成了.

下面要做的, 就是通過網(wǎng)頁發(fā)送請求, 并根據(jù)響應(yīng)構(gòu)建結(jié)果網(wǎng)頁.

網(wǎng)頁構(gòu)建

由于博主沒有學(xué)過前端的代碼, 所以做出來的網(wǎng)頁只是能用. 也沒有能力去解釋一些原理或底層的實現(xiàn). 只能介紹一下基本功能

所以, 直接列出代碼:

./wwwRoot/index.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <title>Boost庫 文檔搜索</title>
    <style>
      /* 去掉網(wǎng)頁中的所有的默認(rèn)內(nèi)外邊距,html的盒子模型 */
      * {
        background-color: #f5f5f7;
        /* 設(shè)置外邊距 */
        margin: 0;
        /* 設(shè)置內(nèi)邊距 */
        padding: 0;
      }

      /* 將我們的body內(nèi)的內(nèi)容100%和html的呈現(xiàn)吻合 */
      html,
      body {
        height: 100%;
      }

      /* 類選擇器.container */
      .container {
        text-align: center;
        /* 設(shè)置div的寬度 */
        width: 800px;
        /* 通過設(shè)置外邊距達(dá)到居中對齊的目的 */
        margin: 0px auto;
        /* 設(shè)置外邊距的上邊距,保持元素和網(wǎng)頁的上部距離 */
        margin-top: 100px;
      }

      /* 復(fù)合選擇器,選中container 下的 search */
      .container .search {
        /* 寬度與父標(biāo)簽保持一致 */
        width: auto;
        /* 高度設(shè)置為52px */
        height: 52px;
      }

      .container .result {
        margin-top: 30px;
        text-align: left;
        width: 100%;
      }

      .container .result .item {
        height: auto;
        border-radius: 13px;
        background-color: #fff;
        box-shadow: 0 0 5px rgb(0, 0, 0, 0.2);
        margin-top: 15px;
        padding-bottom: 10px;
        padding-top: 10px;
      }

      .container .result .item a {
        margin-left: 10px;
        margin-right: 10px;
        /* 設(shè)置為塊級元素,單獨站一行 */
        display: block;
        background-color: #fff;
        /* a標(biāo)簽的下劃線去掉 */
        text-decoration: none;
        /* 設(shè)置a標(biāo)簽中的文字的字體大小 */
        font-size: 20px;
        /* 設(shè)置字體的顏色 */
        color: #4e6ef2;
        word-break: break-all;
      }

      .container .result .item a:hover {
        /*設(shè)置鼠標(biāo)放在a之上的動態(tài)效果*/
        text-decoration: underline;
      }

      .container .result .item p {
        margin-left: 10px;
        margin-top: 10px;
        margin-right: 10px;
        display: block;
        background-color: #fff;
        font-size: 16px;
        word-break: break-all;
        font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande",
          "Lucida SansUnicode", Geneva, Verdana, sans-serif;
      }

      .container .result .item i {
        margin-left: 10px;
        margin-right: 10px;
        /* 設(shè)置為塊級元素,單獨站一行 */
        display: block;
        font-size: 12px;
        /* 取消斜體風(fēng)格 */
        font-style: normal;
        background-color: #fff;
        color: gray;
        word-break: break-all;
      }

      #INDEXBLOGS {
        text-align: center;
        width: 75%;
      }

      .search-box {
        width: 666px;
        margin: auto;
        display: flex;
        background-color: #fff;
        align-items: center;
        border: 1px solid #ddd;
        border-radius: 25px;
        height: 44px;
        box-shadow: 0 0 5px rgb(0, 0, 0, 0.2);
      }

      .search-input {
        flex: 1;
        padding: 0 15px;
        border: none;
        background-color: #fff;
        border: 0px solid #ddd;
        border-radius: 25px;
        font-size: 16px;
        height: 43px;
      }

      .search-input:focus {
        outline: none;
      }

      .search-button {
        padding: 0 18px;
        height: 100%;
        border: none;
        border-radius: 0 25px 25px 0;
        background: #fef9f2;
        color: #666;
        font-size: 16px;
        cursor: pointer;
      }

      .suggestion {
        margin-bottom: 5px;
        color: #000000;
        font-size: 14px;
      }
    </style>
  </head>

  <body>
    <div class="container">
      <img
        src="https://dxyt-july-image.oss-cn-beijing.aliyuncs.com/202308080011153.png"
        id="INDEXBLOGS"
      />
      <p class="suggestion">
        服務(wù)器配置原因, 若搜索結(jié)果過多 可能響應(yīng)較慢, 請耐心等待哦~
      </p>
      <div class="search-box">
        <input
          type="text"
          id="search-input"
          class="search-input"
          placeholder=""
        />
        <button onclick="Search()" class="search-button">&#9829; Search</button>
      </div>
      <div class="result">
     	// 這里是展示搜索結(jié)果的地方
      </div>
    </div>
    <script>
      // 獲取輸入框元素
      const input = document.getElementById("search-input");

      // 輸入框按鍵按下事件監(jiān)聽
      input.addEventListener("keydown", function (event) {
        // 判斷按鍵為回車鍵
        if (event.keyCode === 13) {
          // 模擬按鈕點擊事件
          document.querySelector(".search-button").click();
        }
      });
      function Search() {
        // 是瀏覽器的一個彈出框
        // alert("hello js!");
        // 1. 提取數(shù)據(jù), $可以理解成就是JQuery的別稱
        let query = $(".container .search-input").val();
        console.log("query = " + query); //console是瀏覽器的對話框,可以用來進(jìn)行查看js數(shù)據(jù)

        //2. 發(fā)起http請求,ajax: 屬于一個和后端進(jìn)行數(shù)據(jù)交互的函數(shù),JQuery中的
        $.ajax({
          type: "GET",
          url: "/s?word=" + query,
          success: function (data) {
            console.log(data);
            BuildHtml(data);
          },
        });
      }

      function BuildHtml(data) {
        // 獲取html中的result標(biāo)簽
        let result_lable = $(".container .result");
        // 清空歷史搜索結(jié)果
        result_lable.empty();

        for (let elem of data) {
          // console.log(elem.title);
          // console.log(elem.url);
          let a_lable = $("<a>", {
            text: elem.title,
            href: elem.url,
            // 跳轉(zhuǎn)到新的頁面
            target: "_blank",
          });
          let i_lable = $("<i>", {
            text: elem.url,
          });
          let p_lable = $("<p>", {
            text: elem.desc,
          });
          let div_lable = $("<div>", {
            class: "item",
          });
          a_lable.appendTo(div_lable);
          i_lable.appendTo(div_lable);
          p_lable.appendTo(div_lable);
          div_lable.appendTo(result_lable);
        }
      }
    </script>
  </body>
</html>

這個html文件是創(chuàng)建在項目目錄下的wwwRoot目錄下的:

[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

一個是頁面html文件, 一個是圖標(biāo)文件

大概解釋一下這個html代碼:

  1. 首先最外層 是html最基本的框架:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title></title>
        </head>
        <body>
    
        </body>
    </html>
    

    <body> </body>之間的內(nèi)容, 就是要在頁面中顯示的內(nèi)容

  2. <body> </body>之間. 先設(shè)置了一個<div class="container"> </div>

    可以看作是在頁面內(nèi)容中設(shè)置了一個框架, 之后只要在這個<div>內(nèi)部的 都會顯示在這個框架中

  3. 然后<div class="container"></div>內(nèi)最主要的就是:

    1.  <div class="search-box">
           <input
                  type="text"
                  id="search-input"
                  class="search-input"
                  placeholder=""
                  />
           <button onclick="Search()" class="search-button">&#9829; Search</button>
       </div>
      

      又設(shè)置了一個<div>并在其內(nèi)部設(shè)置了:

      一個搜索框 <input type="text" id="search-input" class="search-input" placeholder="" />

      一個搜索按鈕 <button onclick="Search()" class="search-button">&#9829; Search</button>

      <button> </button>之間是按鈕上顯示的內(nèi)容, onclick="Search()"表示點擊按鈕執(zhí)行的函數(shù)

    2.  <div class="result">
           // 這里是展示搜索結(jié)果的地方
       </div>
      

      搜索框下面就是要展示的內(nèi)容了

      設(shè)置了<div class="result"> </div>, 這個<div>內(nèi)部就是展示搜索結(jié)果用的

      搜索結(jié)果用這個元素item表示:

      <div class="item">
          <a href="" target="_blank">跳轉(zhuǎn)標(biāo)題</a>
          <i>url</i>
          <p>摘要</p>
      </div>
      
  4. 布局設(shè)置完畢之后, 就需要使用JavaScript JQuery ajax來發(fā)送請求, 接收響應(yīng) 和 設(shè)置搜索結(jié)果了

    <script>
        // 獲取輸入框元素
        const input = document.getElementById("search-input");
    
        // 輸入框按鍵按下事件監(jiān)聽
        input.addEventListener("keydown", function (event) {
            // 判斷按鍵為回車鍵
            if (event.keyCode === 13) {
                // 模擬按鈕點擊事件
                document.querySelector(".search-button").click();
            }
        });
        function Search() {
            // 是瀏覽器的一個彈出框
            // alert("hello js!");
            // 1. 提取數(shù)據(jù), $可以理解成就是JQuery的別稱
            let query = $(".container .search-input").val();
            console.log("query = " + query); //console是瀏覽器的對話框,可以用來進(jìn)行查看js數(shù)據(jù)
    
            //2. 發(fā)起http請求,ajax: 屬于一個和后端進(jìn)行數(shù)據(jù)交互的函數(shù),JQuery中的
            $.ajax({
                type: "GET",
                url: "/s?word=" + query,
                success: function (data) {
                    console.log(data);
                    BuildHtml(data);
                },
            });
        }
    
        function BuildHtml(data) {
            // 獲取html中的result標(biāo)簽
            let result_lable = $(".container .result");
            // 清空歷史搜索結(jié)果
            result_lable.empty();
    
            for (let elem of data) {
                // console.log(elem.title);
                // console.log(elem.url);
                let a_lable = $("<a>", {
                    text: elem.title,
                    href: elem.url,
                    // 跳轉(zhuǎn)到新的頁面
                    target: "_blank",
                });
                let i_lable = $("<i>", {
                    text: elem.url,
                });
                let p_lable = $("<p>", {
                    text: elem.desc,
                });
                let div_lable = $("<div>", {
                    class: "item",
                });
                a_lable.appendTo(div_lable);
                i_lable.appendTo(div_lable);
                p_lable.appendTo(div_lable);
                div_lable.appendTo(result_lable);
            }
        }
    </script>
    

    <script> </script>內(nèi)部, 首先設(shè)置了一個監(jiān)聽按鍵的函數(shù). 為了實現(xiàn) 按下回車搜索

    然后就是Search()函數(shù), 獲取search-input搜索框內(nèi)的數(shù)據(jù)為query, 然后創(chuàng)建HTTPGET方法請求, 并攜帶?word=query 發(fā)送給服務(wù)器.

    然后成功接收到響應(yīng)之后, 根據(jù)響應(yīng)數(shù)據(jù) 執(zhí)行Build()函數(shù) 在<div class="result"></div>內(nèi)部 設(shè)置item元素


編寫完index.html之后, 需要在httpServer.cc主函數(shù)內(nèi), 將服務(wù)器的web根文件設(shè)置為./wwwRoot/index.html

const std::string& rootPath = "./wwwRoot/index.html";

svr.set_base_dir(rootPath.c_str());

然后再編譯運行服務(wù)器:

  1. 沒有執(zhí)行搜索的界面:

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

  2. 執(zhí)行了搜索之后的界面:

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

    搜索結(jié)果, 都會按照權(quán)重一個個排列在下面

至此, 我們的Boost搜索引擎就可以使用了!

不過, 還有一些地方需要優(yōu)化和修改

代碼優(yōu)化

當(dāng)前的搜索引擎還有問題:

  1. 沒有搜索到內(nèi)容時, 不會有任何反應(yīng). 可能會讓用戶認(rèn)為服務(wù)器沒有運作.

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

    所以可以考慮在沒有搜索到任何文檔的時候, 響應(yīng)一個沒有任何內(nèi)容的item元素. 并實現(xiàn), 點擊標(biāo)題 跳轉(zhuǎn)回主頁:

    /* searcher.hpp */
    
    // 排序之后, allInvertedElemOut 中文檔的排序就是倒序了
    // 然后 通過遍歷此數(shù)組, 獲取文檔id, 根據(jù)id獲取文檔在正排索引中的內(nèi)容
    // 然后再將 所有內(nèi)容序列化
    Json::Value root;
    if (allInvertedElemOut.empty()) {
        // 如果沒有查找到一個文檔
        Json::Value elem;
        elem["url"] = "http://119.3.223.238:8080";
        elem["title"] = "Search nothing!";
        // 關(guān)于文檔的內(nèi)容, 搜索結(jié)果中是不展示文檔的全部內(nèi)容的, 應(yīng)該只顯示包含關(guān)鍵詞的摘要, 點進(jìn)文檔才顯示相關(guān)內(nèi)容
        // 而docInfo中存儲的是文檔去除標(biāo)簽之后的所有內(nèi)容, 所以不能直接將 doc._content 存儲到elem對應(yīng)key:value中
        elem["desc"] = "Search nothing!";
        root.append(elem);
        // 處理url 都設(shè)置為無效值
    }
    else {
        for (auto& elemOut : allInvertedElemOut) {
            // 通過Json::Value 對象, 存儲文檔內(nèi)容
            Json::Value elem;
            // 通過elemOut._docId 獲取正排索引中 文檔的內(nèi)容信息
            ns_index::docInfo_t* doc = _index->getForwardIndex(elemOut._docId);
            // elem賦值
            elem["url"] = doc->_url;
            elem["title"] = doc->_title;
            // 關(guān)于文檔的內(nèi)容, 搜索結(jié)果中是不展示文檔的全部內(nèi)容的, 應(yīng)該只顯示包含關(guān)鍵詞的摘要, 點進(jìn)文檔才顯示相關(guān)內(nèi)容
            // 而docInfo中存儲的是文檔去除標(biāo)簽之后的所有內(nèi)容, 所以不能直接將 doc._content 存儲到elem對應(yīng)key:value中
            elem["desc"] = getDesc(doc->_content, elemOut._keywords[0]); // 只根據(jù)第一個關(guān)鍵詞來獲取摘要
            // for Debug
            // 這里有一個bug, jsoncpp 0.10.5.2 是不支持long或long long 相關(guān)類型的, 所以需要轉(zhuǎn)換成 double
            // 這里轉(zhuǎn)換成 double不會有什么影響, 因為這兩個參數(shù)只是本地調(diào)試顯示用的.
            elem["docId"] = (double)doc->_docId;
            elem["weight"] = (double)elemOut._weight;
    
            root.append(elem);
        }
    }
    

    此時, 搜索不到內(nèi)容:

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

    點擊就會跳轉(zhuǎn)至主頁.

  2. 可能沒有標(biāo)題:

    當(dāng)搜索到的文章沒有標(biāo)題時, 就不會顯示出來. 顯示不出來也就無法通過標(biāo)題跳轉(zhuǎn)至指定的頁面:

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

    為什么沒有標(biāo)題呢? 不是因為出錯了, 是因為 這篇文章本身就沒有標(biāo)題:

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

    所以, 我們可以考慮修改搜索時獲取標(biāo)題的代碼:

    /* searcher.hpp */
    
    Json::Value root;
    if (allInvertedElemOut.empty()) {
        Json::Value elem;
        elem["url"] = "http://119.3.223.238:8080";
        elem["title"] = "Search nothing!";
        // 關(guān)于文檔的內(nèi)容, 搜索結(jié)果中是不展示文檔的全部內(nèi)容的, 應(yīng)該只顯示包含關(guān)鍵詞的摘要, 點進(jìn)文檔才顯示相關(guān)內(nèi)容
        // 而docInfo中存儲的是文檔去除標(biāo)簽之后的所有內(nèi)容, 所以不能直接將 doc._content 存儲到elem對應(yīng)key:value中
        elem["desc"] = "Search nothing!";
        root.append(elem);
    }
    else {
        for (auto& elemOut : allInvertedElemOut) {
            // 通過Json::Value 對象, 存儲文檔內(nèi)容
            Json::Value elem;
            // 通過elemOut._docId 獲取正排索引中 文檔的內(nèi)容信息
            ns_index::docInfo_t* doc = _index->getForwardIndex(elemOut._docId);
            // elem賦值
            elem["url"] = doc->_url;
            elem["title"] = doc->_title;
            if (doc->_title.empty()) {
                // 如果無標(biāo)題, 將標(biāo)題設(shè)置為TITLE
                elem["title"] = "TITLE";
            }
            // 關(guān)于文檔的內(nèi)容, 搜索結(jié)果中是不展示文檔的全部內(nèi)容的, 應(yīng)該只顯示包含關(guān)鍵詞的摘要, 點進(jìn)文檔才顯示相關(guān)內(nèi)容
            // 而docInfo中存儲的是文檔去除標(biāo)簽之后的所有內(nèi)容, 所以不能直接將 doc._content 存儲到elem對應(yīng)key:value中
            elem["desc"] = getDesc(doc->_content, elemOut._keywords[0]); // 只根據(jù)第一個關(guān)鍵詞來獲取摘要
            // for Debug
            // 這里有一個bug, jsoncpp 0.10.5.2 是不支持long或long long 相關(guān)類型的, 所以需要轉(zhuǎn)換成 double
            // 這里轉(zhuǎn)換成 double不會有什么影響, 因為這兩個參數(shù)只是本地調(diào)試顯示用的.
            elem["docId"] = (double)doc->_docId;
            elem["weight"] = (double)elemOut._weight;
    
            root.append(elem);
        }
    }
    

    然后, 再搜索:

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

  3. 我們之前為了方便觀測調(diào)試, 把文檔的docIdweight也存儲并發(fā)送了. 現(xiàn)在可以去除

  4. 在使用parser模塊處理文檔html文件的時候, 有三個符號被轉(zhuǎn)換成了編碼<: &lt; >: &gt; &: &amp;

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

    搜索的結(jié)果在頁面中顯示的時候, < > & 符號會以編碼的形式顯示. 所以我們可以在構(gòu)建結(jié)果的的時候, 再將其轉(zhuǎn)換回去:

    /*index.html*/
    
    for (let elem of data) {
        // console.log(elem.title);
        // console.log(elem.url);
        let a_lable = $("<a>", {
            text: elem.title.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&"),
            href: elem.url,
            // 跳轉(zhuǎn)到新的頁面
            target: "_blank",
        });
        let i_lable = $("<i>", {
            text: elem.url,
        });
    
        let p_lable = $("<p>", {
            text: elem.desc.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&"),
        });
        let div_lable = $("<div>", {
            class: "item",
        });
        a_lable.appendTo(div_lable);
        i_lable.appendTo(div_lable);
        p_lable.appendTo(div_lable);
        div_lable.appendTo(result_lable);
    }
    

    [C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...,C++項目實戰(zhàn)-Boost庫文檔站內(nèi)搜索,c++,搜索引擎,html,服務(wù)器,項目,http,linux

添加日志 并 部署服務(wù)器

這部分涉及到守護(hù)進(jìn)程相關(guān)內(nèi)容, 建議閱讀博主文章了解:

??[Linux] 守護(hù)進(jìn)程介紹、服務(wù)器的部署、日志文件…

直接在項目中引入兩個文件, 這兩個文件都是之前實現(xiàn)過 只不過做了一點點修改的. 很簡單:

logMessage.hpp:

/* 日志相關(guān) */

#pragma once

#include <cassert>
#include <cerrno>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

// 宏定義 四個日志等級
#define DEBUG 0
#define NOTICE 1
#define WARNING 2
#define FATAL 3

#define LOGFILEPATH "serverLog.log"

const char* log_level[] = {"DEBUG", "NOTICE", "WARNING", "FATAL"};

class log {
public:
    log()
        : _logFd(-1) {}

    void enable() {
        umask(0);

        _logFd = open(LOGFILEPATH, O_WRONLY | O_CREAT | O_APPEND, 0666);
        assert(_logFd != -1);
        dup2(_logFd, STDOUT_FILENO);
        dup2(_logFd, STDERR_FILENO);
    }

    ~log() {
        if (_logFd != -1) {
            // 將系統(tǒng)緩沖區(qū)內(nèi)容刷入文件
            fsync(_logFd);
            close(_logFd);
        }
    }

private:
    int _logFd;
};

#define LOG(LEVEL, MESSAGE, ...) logMessage(LEVEL, (__FILE__), (__LINE__), MESSAGE, ##__VA_ARGS__)
// 實現(xiàn)一個 可以輸出: 日志等級、日志時間、用戶、以及相關(guān)日志內(nèi)容的
// 日志消息打印接口
void logMessage(int level, const char* file, int line, const char* format, ...) {
    // 通過可變參數(shù)實現(xiàn), 傳入日志等級, 日志內(nèi)容格式, 日志內(nèi)容相關(guān)參數(shù)

    // 確保日志等級正確
    assert(level >= DEBUG);
    assert(level <= FATAL);

    // 獲取當(dāng)前用戶名
    char* name = getenv("USER");

    // 簡單的定義log緩沖區(qū)
    char logInfo[1024];

    // 定義一個指向可變參數(shù)列表的指針
    va_list ap;
    // 將 ap 指向可變參數(shù)列表中的第一個參數(shù), 即 format 之后的第一個參數(shù)
    va_start(ap, format);

    // 此函數(shù) 會通過 ap 遍歷可變參數(shù)列表, 然后根據(jù) format 字符串指定的格式,
    // 將ap當(dāng)前指向的參數(shù)以字符串的形式 寫入到logInfo緩沖區(qū)中
    vsnprintf(logInfo, sizeof(logInfo) - 1, format, ap);

    // ap 使用完之后, 再將 ap置空
    va_end(ap); // ap = NULL

    // 通過判斷日志等級, 來選擇是標(biāo)準(zhǔn)輸出流還是標(biāo)準(zhǔn)錯誤流
    FILE* out = (level == FATAL) ? stderr : stdout;

    // 獲取本地時間
    time_t tm = time(nullptr);
    struct tm* localTm = localtime(&tm);
    char* localTmStr = asctime(localTm);
    char* nC = strstr(localTmStr, "\n");
    if (nC) {
        *nC = '\0';
    }
    fprintf(out, "%s | %s | %s | %s | %s:%d\n", log_level[level], localTmStr,
            name == nullptr ? "unknow" : name, logInfo, file, line);

    // 將C緩沖區(qū)的內(nèi)容 刷入系統(tǒng)
    fflush(out);
    // 將系統(tǒng)緩沖區(qū)的內(nèi)容 刷入文件
    fsync(fileno(out));
}

daemonize.hpp:

/* 守護(hù)進(jìn)程接口 */
#pragma once

#include <cstdio>
#include <fcntl.h>
#include <iostream>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

void daemonize() {
    int fd = 0;

    // 1. 忽略SIGPIPE
    signal(SIGPIPE, SIG_IGN);
    // 2. 改變工作路徑
    // chdir(const char *__path);
    // 3. 不要成為進(jìn)程組組長

    if (fork() > 0) {
        exit(0);
    }
    // 4. 創(chuàng)建獨立會話
    setsid();
    // 重定向文件描述符0 1 2
    if ((fd = open("/dev/null", O_RDWR)) != -1) { // 執(zhí)行成功fd大概率為3
        dup2(fd, STDIN_FILENO);
        dup2(fd, STDOUT_FILENO);
        dup2(fd, STDERR_FILENO);

        // dup2三個標(biāo)準(zhǔn)流之后, fd就沒有用了
        if (fd > STDERR_FILENO) {
            close(fd);
        }
    }
}

在項目中引入這兩個文件之后, 就可以將httpServer.cc設(shè)置為守護(hù)進(jìn)程.

并將 整個項目中所有向標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤打印日志的信息, 都改為LOG(LEVEL, MESSAGE, ...)形式 向文件中打印日志:

#include <iostream>
#include <pthread.h>
#include "util.hpp"
#include "daemonize.hpp"
#include "searcher.hpp"
#include "logMessage.hpp"
#include "httplib.h"

const std::string& input = "./data/output/raw";
const std::string& rootPath = "./wwwRoot";

int main() {
    // 守護(hù)進(jìn)程設(shè)置, 部署服務(wù)器
    daemonize();
    // 日志系統(tǒng)
    class log logSvr;
    logSvr.enable();

    ns_searcher::searcher searcher;
    searcher.initSearcher(input);

    httplib::Server svr;

    svr.set_base_dir(rootPath.c_str());
    svr.Get("/s", [&searcher](const httplib::Request& request, httplib::Response& response) {
        // 首先, 網(wǎng)頁發(fā)起請求 如果需要帶參數(shù), 則是需要以 key=value的格式在url中 或者 正文有效中傳參的
        // 就像我們使用一般搜索引擎搜索一樣:
        // 如果在 google搜索http, 那么 url就會變?yōu)?https://www.google.com/search?q=http&sxsrf=AB5stBgDxDV91zrABB
        // 其中 q=http 就是一對 key=value 值, 而 httplib::Request::has_param() 就是識別請求url中是否攜帶了 某個key=value
        // 本項目中, 我們把搜索內(nèi)容 的key=value對, 設(shè)置為word=搜索內(nèi)容
        if (!request.has_param("word")) {
            // url中沒有 word 鍵值
            // set_content() 第一個參數(shù)是設(shè)置正文內(nèi)容, 第二個參數(shù)是 正文內(nèi)容類型等屬性
            response.set_content("請輸入內(nèi)容后搜索", "text/plain; charset=utf-8");
        }
        std::string searchContent = request.get_param_value("word");
        LOG(NOTICE, "User search:: %s", searchContent.c_str()); 	// 調(diào)用LOG()
        // std::cout << "User search:: " << searchContent << std::endl;

        std::string searchJsonResult;
        searcher.search(searchContent, &searchJsonResult);
        // 搜獲取到搜索結(jié)果之后 設(shè)置相應(yīng)內(nèi)容
        response.set_content(searchJsonResult, "application/json");
    });
    // svr.Get("/hi", [](const httplib::Request&, httplib::Response& res) {
    //  res.set_content("Hello World!", "text/plain");
    // });

    LOG(NOTICE, "服務(wù)器啟動成功...");
    // std::cout << "服務(wù)器啟動成功..." << std::endl;
    svr.listen("0.0.0.0", 8080);

    return 0;
}

執(zhí)行了daemonize()之后, 服務(wù)器就會變成守護(hù)進(jìn)程. 只要服務(wù)器主機不關(guān)機 或者 不主動kill掉進(jìn)程. 服務(wù)就會一直在后臺運行. 所有人都可以隨時隨地訪問.

歡迎訪問: Boost庫 文檔搜索

不歡迎搞破壞!!

項目的完整目錄結(jié)構(gòu) 以及 完整代碼 展示

目錄結(jié)構(gòu)

? pwd
/home/July/gitCode/gitHub/Boost-Doc-Searcher
? tree -L 3
.
├── cppjieba
│   ├── DictTrie.hpp
│   ├── ...(jieba庫相關(guān)頭文件)
│   └── Unicode.hpp
├── cppjiebaDict
│   ├── hmm_model.utf8
│   ├── ...(jieba庫提供的分詞庫)
│   └── user.dict.utf8
├── daemonize.hpp
├── data
│   ├── input
│   │   ├── about.html
│   │   ├── ...(Boost庫文檔文件)
│   │   └── yap.html
│   └── output
│       └── raw
├── httplib.h
├── httpServer.cc
├── index.hpp
├── LICENSE
├── logMessage.hpp
├── makefile
├── parser
├── parser.cc
├── README.md
├── searcher.hpp
├── searcherServerd
├── serverLog.log
├── util.hpp
└── wwwRoot
    ├── favicon.svg
    └── index.html

64 directories, 287 files

完整代碼

整個項目的完整代碼已提交至Github: Boost-Doc-Searcher

歡迎收藏使用~


本篇文章至此結(jié)束. 但此項目還有擴(kuò)展內(nèi)容, 可以關(guān)注一下專欄等待后續(xù)更新~

感謝閱讀~文章來源地址http://www.zghlxwxcb.cn/news/detail-642172.html

到了這里,關(guān)于[C++項目] Boost文檔 站內(nèi)搜索引擎(5): cpphttplib實現(xiàn)網(wǎng)絡(luò)服務(wù)、html頁面實現(xiàn)、服務(wù)器部署...的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Boost搜索引擎項目

    Boost搜索引擎項目

    目錄 1.項目相關(guān)背景 2.搜索引擎的相關(guān)宏觀原理 3.搜索引擎技術(shù)棧和項目環(huán)境 4.正排索引 倒排索引--搜索引擎原理 5.編寫數(shù)據(jù)去標(biāo)簽與數(shù)據(jù)清洗的模塊 -- parser.hpp 去標(biāo)簽 編寫parser(將文件去標(biāo)簽) 編寫EnumFile函數(shù) 編寫ParseFile函數(shù) 解析三大部分: 編寫SaveFile函數(shù) 6.建立索引--編寫

    2024年02月01日
    瀏覽(21)
  • 【Boost搜索引擎項目】

    【Boost搜索引擎項目】

    1.編寫數(shù)據(jù)去標(biāo)簽?zāi)K–parser.cc 將去標(biāo)簽之后干凈文檔以title3content3urlntitle3content3urln格式放入同一文件中。 2.建立索引模塊–index.hpp 讀取處理好的行文本文件進(jìn)行分詞、權(quán)重計算等操作,在內(nèi)存中構(gòu)造出正排索引和倒排索引。 3.編寫搜索引擎模塊–searcher.hpp 對查詢詞進(jìn)

    2024年02月15日
    瀏覽(25)
  • 【項目】Boost搜索引擎

    【項目】Boost搜索引擎

    研發(fā)搜索引擎的公司,如百度、搜狗、360搜索,還有各大網(wǎng)站各種客戶端也提供搜索功能 為什么選擇實現(xiàn)Boost搜索引擎 1)因為Boost官方網(wǎng)站是沒有搜索功能的,所以我們可以為Boost實現(xiàn)一個站內(nèi)搜索引擎,雖然官方提供了boost相關(guān)的一些方法,標(biāo)準(zhǔn)庫中的一些接口,但是我們想看到

    2024年02月03日
    瀏覽(27)
  • 【C++項目】boost搜索引擎

    【C++項目】boost搜索引擎

    boost官網(wǎng) Boost庫是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。 Boost庫由Boost社區(qū)組織開發(fā)、維護(hù)。其目的是為C++程序員提供免費、同行審查的、可移植的程序庫。Boost庫可以與C++標(biāo)準(zhǔn)庫完美共同工作,并且為其提供擴(kuò)展功能。Boost庫使用Boost License來授權(quán)使用,根據(jù)該協(xié)議

    2023年04月16日
    瀏覽(28)
  • 基于boost庫的搜索引擎項目

    基于boost庫的搜索引擎項目

    boost庫是指一些為C++標(biāo)準(zhǔn)庫提供擴(kuò)展的程序庫總稱,但是boost網(wǎng)站中并沒有為我們提供站內(nèi)搜索功能,因此我們要想找到某一個類的用法還要一個個去找,因此我們這次的目的就是實現(xiàn)一個搜索引擎功能,提高我們獲取知識的效率 比如百度,谷歌,360等,這些都是大型的搜索

    2024年03月14日
    瀏覽(29)
  • 基于boost準(zhǔn)標(biāo)準(zhǔn)庫的搜索引擎項目

    基于boost準(zhǔn)標(biāo)準(zhǔn)庫的搜索引擎項目

    這是一個基于Web的搜索服務(wù)架構(gòu) 客戶端-服務(wù)器模型 :采用了經(jīng)典的客戶端-服務(wù)器模型,用戶通過客戶端與服務(wù)器交互,有助于集中管理和分散計算。 簡單的用戶界面 :客戶端似乎很簡潔,用戶通過簡單的HTTP請求與服務(wù)端交互,易于用戶操作。 搜索引擎功能 :服務(wù)器端的

    2024年04月27日
    瀏覽(15)
  • 【Boost搜索引擎項目】Day1 項目介紹+去標(biāo)簽和數(shù)據(jù)清洗框架搭建

    【Boost搜索引擎項目】Day1 項目介紹+去標(biāo)簽和數(shù)據(jù)清洗框架搭建

    ??歡迎來到C++項目專欄 ?????♀?作者介紹:前PLA隊員 目前是一名普通本科大三的軟件工程專業(yè)學(xué)生 ??IP坐標(biāo):湖北武漢 ?? 目前技術(shù)棧:C/C++、Linux系統(tǒng)編程、計算機網(wǎng)絡(luò)、數(shù)據(jù)結(jié)構(gòu)、Mysql、Python ?? 博客介紹:通過分享學(xué)習(xí)過程,加深知識點的掌握,也希望通過平臺能

    2024年03月23日
    瀏覽(26)
  • 站內(nèi)搜索引擎

    站內(nèi)搜索引擎

    1.什么是搜索引擎? 如圖所示: 我用的是谷歌瀏覽器,但是我的搜索引擎可以跟換 。切換到bing主頁 在搜索框中我們輸入一段話,跳到一個帶有搜索結(jié)果的頁面如下: 搜索引擎的核心功能:查找用戶輸入的詞/一句話 相關(guān)聯(lián)的網(wǎng)頁。? 搜索結(jié)果頁一條記錄包含的信息如下:

    2023年04月11日
    瀏覽(24)
  • 什么是站內(nèi)搜索引擎?如何在網(wǎng)站中加入站內(nèi)搜索功能?

    什么是站內(nèi)搜索引擎?如何在網(wǎng)站中加入站內(nèi)搜索功能?

    在當(dāng)今數(shù)字時代,用戶體驗對于網(wǎng)站的成功起著至關(guān)重要的作用。提升用戶體驗和改善整體網(wǎng)站性能的一種方法是引入站內(nèi)搜索引擎。站內(nèi)搜索引擎是一種強大的工具,它的功能類似于Google或Bing等流行搜索引擎,但它專注于實施自己網(wǎng)站上的內(nèi)容。用戶可以在網(wǎng)站內(nèi)搜索特定

    2024年02月03日
    瀏覽(38)
  • Java項目——文檔搜索引擎

    Java項目——文檔搜索引擎

    實現(xiàn)一個較為簡單的搜索引擎,在擁有較多網(wǎng)頁的基礎(chǔ)上,在用戶輸入查詢詞之后,能夠從這些網(wǎng)頁中盡可能地匹配出用戶想要的網(wǎng)頁 當(dāng)然,不同于百度搜狗這種搜索引擎,它們能夠?qū)ヂ?lián)網(wǎng)中大量的網(wǎng)站都進(jìn)行搜索,我們這里實現(xiàn)的是針對「Java 文檔」的搜索引擎,就像下

    2024年02月02日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包