美文网首页
C++ micro web framework -- crow

C++ micro web framework -- crow

作者: auguszou | 来源:发表于2017-06-10 17:46 被阅读0次

    It's so wonderful to hear about crow, a web framework to develop web application with cpp.
    github.com
    A exampe from offical

    #include "crow.h"
    
    int main()
    {
        crow::SimpleApp app;
    
        CROW_ROUTE(app, "/")([](){
            return "Hello world";
        });
    
        app.port(18080).multithreaded().run();
    }
    

    route

    crow define a macro CROW_ROUTE(app, url)

    #ifdef CROW_MSVC_WORKAROUND
    #define CROW_ROUTE(app, url) app.route_dynamic(url)
    #else
    #define CROW_ROUTE(app, url) app.route<crow::black_magic::get_parameter_tag(url)>(url)
    #endif
    

    params

    #include "crow.h"
    
    int main()
    {
        crow::SimpleApp app;
    
        CROW_ROUTE(app, "/")([](){
            return "Hello world";
        });
        CROW_ROUTE(app,"/hello/<int>")
          ([](int count){
           if (count > 100)
           return crow::response(400);
           std::ostringstream os;
           os << count << " bottles of beer!";
           return crow::response(os.str());
           });
        CROW_ROUTE(app, "/params")
           ([](const crow::request& req){
              std::ostringstream os;
              os << "Params: " << req.url_params << "\n\n"; 
              os << "The key 'foo' was " << (req.url_params.get("foo") == nullptr ? "not " : "") << "found.\n";
              if(req.url_params.get("pew") != nullptr) {
                  double countD = boost::lexical_cast<double>(req.url_params.get("pew"));
                  os << "The value of 'pew' is " <<  countD << '\n';
              }
              auto count = req.url_params.get_list("count");
              os << "The key 'count' contains " << count.size() << " value(s).\n";
              for(const auto& countVal : count) {
                  os << " - " << countVal << '\n';
              }
              return crow::response{os.str()};
              }); 
    
        app.port(18080).multithreaded().run();
    }
    

    json

    #include "crow.h"
    
    int main()
    {
        crow::SimpleApp app;
    
        CROW_ROUTE(app, "/json")
        ([]{
         crow::json::wvalue x;
         x["message"] = "Hello, World!";
         return x;
         });
    
        app.port(18080).run();
    }
    

    header

    #include "crow.h"
    
    int main()
    {
        crow::SimpleApp app;
    
        CROW_ROUTE(app, "/")
        ([](const crow::request& req){
         std::ostringstream os;
         // ci_map req.header
         os << "Headers Server: " << req.get_header_value("test") << "\n\n"; 
            return req.get_header_value("test");
        });
    
        app.port(18080).run();
    }
    
    

    middleware

    #include "crow.h"
    
    #include <sstream>
    
    class ExampleLogHandler : public crow::ILogHandler {
        public:
            void log(std::string message, crow::LogLevel level) override {
    //            cerr << "ExampleLogHandler -> " << message;
            }
    };
    
    struct ExampleMiddleware 
    {
        std::string message;
    
        ExampleMiddleware() 
        {
            message = "foo";
        }
    
        void setMessage(std::string newMsg)
        {
            message = newMsg;
        }
    
        struct context
        {
        };
    
        void before_handle(crow::request& req, crow::response& res, context& ctx)
        {
            CROW_LOG_DEBUG << " - MESSAGE: " << message;
        }
    
        void after_handle(crow::request& req, crow::response& res, context& ctx)
        {
            // no-op
        }
    };
    
    int main()
    {
        crow::App<ExampleMiddleware> app;
    
        app.get_middleware<ExampleMiddleware>().setMessage("hello");
    
        app.route_dynamic("/")
        ([]{
            return "Hello World!";
        });
    
        app.route_dynamic("/about")
        ([](){
            return "About Crow example.";
        });
    
        // a request to /path should be forwarded to /path/
        app.route_dynamic("/path/")
        ([](){
            return "Trailing slash test case..";
        });
    
        // simple json response
        app.route_dynamic("/json")
        ([]{
            crow::json::wvalue x;
            x["message"] = "Hello, World!";
            return x;
        });
    
        app.route_dynamic("/hello/<int>")
        ([](int count){
            if (count > 100)
                return crow::response(400);
            std::ostringstream os;
            os << count << " bottles of beer!";
            return crow::response(os.str());
        });
    
        app.route_dynamic("/add/<int>/<int>")
        ([](const crow::request& req, crow::response& res, int a, int b){
            std::ostringstream os;
            os << a+b;
            res.write(os.str());
            res.end();
        });
    
        // Compile error with message "Handler type is mismatched with URL paramters"
        //CROW_ROUTE(app,"/another/<int>")
        //([](int a, int b){
            //return crow::response(500);
        //});
    
        // more json example
        app.route_dynamic("/add_json")
            .methods(crow::HTTPMethod::POST)
        ([](const crow::request& req){
            auto x = crow::json::load(req.body);
            if (!x)
                return crow::response(400);
            auto sum = x["a"].i()+x["b"].i();
            std::ostringstream os;
            os << sum;
            return crow::response{os.str()};
        });
    
        app.route_dynamic("/params")
        ([](const crow::request& req){
            std::ostringstream os;
            os << "Params: " << req.url_params << "\n\n"; 
            os << "The key 'foo' was " << (req.url_params.get("foo") == nullptr ? "not " : "") << "found.\n";
            if(req.url_params.get("pew") != nullptr) {
                double countD = boost::lexical_cast<double>(req.url_params.get("pew"));
                os << "The value of 'pew' is " <<  countD << '\n';
            }
            auto count = req.url_params.get_list("count");
            os << "The key 'count' contains " << count.size() << " value(s).\n";
            for(const auto& countVal : count) {
                os << " - " << countVal << '\n';
            }
            return crow::response{os.str()};
        });    
    
        // ignore all log
        crow::logger::setLogLevel(crow::LogLevel::DEBUG);
        //crow::logger::setHandler(std::make_shared<ExampleLogHandler>());
    
        app.port(18080)
            .multithreaded()
            .run();
    }
    

    websocket

    #include "crow.h"
    #include <string>
    #include <vector>
    #include <chrono>
    
    using namespace std;
    
    vector<string> msgs;
    vector<pair<crow::response*, decltype(chrono::steady_clock::now())>> ress;
    
    void broadcast(const string& msg)
    {
        msgs.push_back(msg);
        crow::json::wvalue x;
        x["msgs"][0] = msgs.back();
        x["last"] = msgs.size();
        string body = crow::json::dump(x);
        for(auto p:ress)
        {
            auto* res = p.first;
            CROW_LOG_DEBUG << res << " replied: " << body;
            res->end(body);
        }
        ress.clear();
    }
    // To see how it works go on {ip}:40080 but I just got it working with external build (not directly in IDE, I guess a problem with dependency)
    int main()
    {
        crow::SimpleApp app;
        crow::mustache::set_base(".");
    
        CROW_ROUTE(app, "/")
        ([]{
            crow::mustache::context ctx;
            return crow::mustache::load("example_chat.html").render();
        });
    
        CROW_ROUTE(app, "/logs")
        ([]{
            CROW_LOG_INFO << "logs requested";
            crow::json::wvalue x;
            int start = max(0, (int)msgs.size()-100);
            for(int i = start; i < (int)msgs.size(); i++)
                x["msgs"][i-start] = msgs[i];
            x["last"] = msgs.size();
            CROW_LOG_INFO << "logs completed";
            return x;
        });
    
        CROW_ROUTE(app, "/logs/<int>")
        ([](const crow::request& /*req*/, crow::response& res, int after){
            CROW_LOG_INFO << "logs with last " << after;
            if (after < (int)msgs.size())
            {
                crow::json::wvalue x;
                for(int i = after; i < (int)msgs.size(); i ++)
                    x["msgs"][i-after] = msgs[i];
                x["last"] = msgs.size();
    
                res.write(crow::json::dump(x));
                res.end();
            }
            else
            {
                vector<pair<crow::response*, decltype(chrono::steady_clock::now())>> filtered;
                for(auto p : ress)
                {
                    if (p.first->is_alive() && chrono::steady_clock::now() - p.second < chrono::seconds(30))
                        filtered.push_back(p);
                    else
                        p.first->end();
                }
                ress.swap(filtered);
                ress.push_back({&res, chrono::steady_clock::now()});
                CROW_LOG_DEBUG << &res << " stored " << ress.size();
            }
        });
    
        CROW_ROUTE(app, "/send")
            .methods("GET"_method, "POST"_method)
        ([](const crow::request& req)
        {
            CROW_LOG_INFO << "msg from client: " << req.body;
            broadcast(req.body);
            return "";
        });
    
        app.port(40080)
            //.multithreaded()
            .run();
    }
    

    相关文章

      网友评论

          本文标题:C++ micro web framework -- crow

          本文链接:https://www.haomeiwen.com/subject/amxxqxtx.html