高性能現代C++ Web框架:Cinatra

jopen 10年前發布 | 50K 次閱讀 Cinatra Web框架

cinatra是一個現代C++寫的web framework,它的目的是給用戶提供一個易用、靈活和高性能的web框架,讓用戶能完全專注于核心邏輯而無需關注http細節。它的靈感來源于sinatra,但又有自己的特色。

Cinatra的設計非常簡單,只有幾個組件,下面是Cinatra的邏輯視圖。

高性能現代C++ Web框架:Cinatra

Cinatra邏輯視圖

用戶僅用Cinatra即可,其它的事情框架已經幫用戶做好了,用戶只用關注核心邏輯即可,這些核心邏輯都在handler中處理,而這些handler完全由用戶自定義和擴展。

如何使用

1.從 github 上下載源碼。

2.安裝boost,因為框架用到asio和coroutine,需要1.57及以上的版本。

3.編譯。已經提供vs2013的工程文件和Cmakelist,直接在win和linux平臺下編譯即可。

示例

C++

#include <cinatra/cinatra.hpp>
using namespace cinatra;
int main()
{
    SimpleApp app;
    app.route("/", [](Request&  req , Response& res)
    {
        res.end("Hello Cinatra");
    });

    app.listen("http").run();

    return 0;
}

運行起來之后,在瀏覽器中輸入:127.0.0.1就可以看到返回的” Hello Cinatra”, 用起來是不是很簡單,cinatra框架幫你把很多事情都做好了,你只需要關注你的核心業務邏輯即可。讓我們繼續看一個稍微復雜一點的例子。

C++

#include <cinatra/cinatra.hpp>
using namespace cinatra;
int main()
{
    SimpleApp app;
    app.route("/hello", [](Request&  req , Response& res)
    {
    res.end("Hello " + req.query().get_val("name"));    
     });
    app.route("/hello/:name/:age", [](Request& req, Response& res, const std::string& a, int b)
    {
        res.end("Name: " + a + " Age: " + boost::lexical_cast<std::string>(b));
    });

    app.listen("http").run();

    return 0;
}

瀏覽器中輸入:127.0.0.1/hello?name=test&age=12,頁面將輸出” Hello test”。 為了讓用戶用起來更方便,我們還支持下面這種url請求方式:127.0.0.1/hello/test/12,這個url將會被路由到”/hello/:name/:age”對應的handler:[](Request& req, Response& res, const std::string& a, int b);

Router不僅僅支持lambda表達式還支持類的成員函數,如果你想把handler放到類對象中,你可以這樣做。

C++

struct MyStruct
{
    void hello(Request& req, Response& res)
    {
        res.end("Hello " + req.session().get<std::string>("uid") + "!");
    }
};
MyStruct t;
// 訪問/hello
app.route("/hello", &MyStruct::hello, &t);

cinatra不僅僅使用簡單,還很靈活,它支持AOP,我們可以很方便的將非核心邏輯和核心邏輯分離,比如下面的例子。

C++

struct CheckLoginAspect
{
    void before(Request& req, Response& res)
    {
        //如果session沒有uid且訪問的不是login和test_post頁面
        if (!req.session().exists("uid")&&req.path()!="/login.html"&&
            req.path() != "/test_post"&&req.path().compare(0, 7, "/public"))
        {
            // 跳轉到登陸頁面
            res.redirect("/login.html");
        }
    }

    void after(Request&  req , Response&  res)
    {

    }
};

#include <cinatra/cinatra.hpp>
using namespace cinatra;
int main()
{
    Cinatra<CheckLoginAspect> app;
    app.route("/", [](Request&  req , Response& res)
    {
        res.end("Hello Cinatra");
    });
    app.listen("http").run();

    return 0;
}

上面的例子中我們增加了一個檢查是否登錄的切面,如果用戶沒登錄將會重定向到登錄頁面。我們還可以自由組合多個切面,cinatra可以很方便地擴展任意多個切面。你可以這樣擴展切面。

C++

struct CheckLoginAspect
{
    void before(Request& req, Response& res)
    {
        //如果session沒有uid且訪問的不是login和test_post頁面
        if (!req.session().exists("uid")&&req.path()!="/login.html"&&
            req.path() != "/test_post"&&req.path().compare(0, 7, "/public"))
        {
            // 跳轉到登陸頁面
            res.redirect("/login.html");
        }
    }

    void after(Request&  req , Response&  res)
    {

    }
};

struct LogAspect
{
    void before(cinatra::Request& req, cinatra::Response& res)
    {
        std::cout << "log before" << std::endl;
    }

    void after(cinatra::Request& /* req */, cinatra::Response& /* res */)
    {
        std::cout << "log after" << std::endl;
    }
};

#include <cinatra/cinatra.hpp>
using namespace cinatra;
int main()
{
    Cinatra<CheckLoginAspect, LogAspect> app; //擴展了一個記錄日志的切面
    app.route("/", [](Request&  req , Response& res)
    {
        res.end("Hello Cinatra");
    });

    app.listen("http").run();

    return 0;
}

性能

用ab工具和另外一個c++ web框架 crow 做了一下性能對比:

crow:

高性能現代C++ Web框架:Cinatra

cinatra:

高性能現代C++ Web框架:Cinatra

可以看到cinatra比crow的性能略高。現在第一個版本還沒有專門去做優化,主要是完成了基本功能,后續會持續優化的,也歡迎大家幫忙做進一步的性能測試。

roadmap

目前支持了http1.0和1.1,支持了session和cookie,后續計劃:

  • https
  • html模板
  • websocket
  • cinatra打造purecpp社區

開發和參與者

C++開源社區:http://purecpp.org/,江南,網事如風,SIGSEGV,海盜,福爾摩斯喵。

更多的例子請到社區和 github 上看。

如果你發現了問題請及時到社區反饋給我們,也歡迎提出寶貴意見。希望更多的人能參與進來。

如果你覺得cinatra不錯,請不要吝惜給一個star^_^。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!