基于C++的高性能http框架cinatra及其web框架示例feather介绍及开发演示

1 篇文章 0 订阅

说起web开发框架,一定会想到java,php,python等快速开发语言,在从多web开发技术中少有使用C++进行开发,虽然C++性能优越,但是由于开发周期长,语言本身的复杂性,不符合当前快速敏捷开发的要求,正因如此也少有web方面的开源框架。

cinatra介绍

github地址:https://github.com/qicosmos/cinatra

cinatra是一个高性能易用的http框架,使用c++17开发,所以编译gcc7以上,本示例在linux平台上使用gcc9.2,windows平台推荐vs2017以上,本示例使用vs2019 community。

cinatra框架支持跨平台并且类拟于boost,整个库header-only因此很容易添加到项目中。整个cinatra框架结构类拟于springmvc,支持面向切面编程。

github上同时有一个使用cinatra框架的web示例,就是feather,github地址 https://github.com/qicosmos/feather

具体的cinatra和feather介绍可到github的项目主页上查看。

首先从github上把feather项目clone下来,项目里包含了windows平台的vs项目文件和cmake文件方便在linux下进行编译。

clone时同时把依赖项clone下来:

cinatra 高性能C++17的http框架

iguana 序列化引擎

ormpp 高性能C++17的ORM框架

render html模板引擎

 

git clone --recursive https://github.com/qicosmos/feather.git

cinatra是基于boost.asio开发,所以需要使用boost库,虽然介绍中说可以支持ASIO_STANDALONE,不一定需要boost库,但是为了简化示例,这边使用boost最新的库,boost1.72。

介绍一下本人编译环境,

windows平台

windows10,vs2019,mariadb c++连接库,boost1.72,编译为64位程序(64位替换32位是趋势)

linux平台

debian10 buster testing,libmysql,boost1.62, gcc9.2,gcc和boost可直接apt install安装。

代码修改编写均在windows平台的vs2019中完成,在linux下直接cmake即可,这里不详述

由于本人的windows平台安装的是mariadb数据库,没有安装mysql因此需修改ormpp框架中type_mapping.hpp中的头文件包含,以适配mariadb,在此不详述,其他使用与mysql一致。

feather项目中带有数据库初始化脚本feather.sql直接导入数据库即可(先新建数据库用户feather)

在vs中配置完boost库和mariadb conntor库的目录后,可直接编译生成feather.exe文件。把静态文件复制到与feather.exe同一目录即可测试运行。效果如下:

整体上已经有一个网站基本的功能了,包括用户登录,角色,内容管理,新闻管理,公告消息,文件管理等功能。

现在我们在上排导航菜单上再加一个“工作台”,使用H+的前端框架,使用mvc架构让这个“工作台”知道登录的用户和角色,如果没有登录,打开此“工作台”则跳转至登录页面。

我们打开feather项目中的main.cpp文件,在上面可以看到很多现成的http handle,比如:

主页是:

server.set_http_handler<GET>("/", &purecpp_controller::home, &purecpp_ctl, check_start_end_input{});
server.set_http_handler<GET>("/home", &purecpp_controller::home, &purecpp_ctl, check_start_end_input{});

可以看到/home和/ 会跳转到同一个home控制器。

现在我们添加一个自已的http handle,同时添加一个controller用来处理我们的“工作台”

在main.cpp中添加:

server.set_http_handler<GET, POST>("/workdash", &purecpp_controller::workdash, &purecpp_ctl, check_start_end_input{});

在purecpp_controller.hpp中添加控制器:


void workdash(request& req, response& res) {
    auto session = req.get_session().lock();
    if (session == nullptr || session->get_data<std::string>("user_name").empty()) {
        std::cout << "redirect to login page." << std::endl;
		render_simple_page(req, res, "./purecpp/html/login.html", "login");
	}
	else {
		render_simple_page(req, res, "./purecpp/html/workdash/index.html", "workdash");
	}
}

说明:

feather原本的静态文件夹与exe文件在同一目录,我们的workdash就存放在html目录下新的workdash(把整个h+框架的html复制到此),并且把整个H+的静态文件在 ./purecpp/workdash目录中(并修改相应的html页面)

首先从session中判断是否为登录状态,如果未登录就跳转到登录页面。

如果只是这样,虽然编译完全没问题 ,但是从workdash跳转到登录页面后,无论怎么样,都无法登录,并且提示用户名密码错误。这是什么原因呢?

我们看到登录页面的controller是login_page,提交登录的controller是login,login_page没什么好说的,只是一个页面渲染。

我们看一下login控制器:

void login(request& req,response& res){

    const auto& params = req.get_aspect_data();

    const auto& user_name = params[0];

    const auto& password = params[1];

………………

}

我们看到login控制器中的用户名和密码信息不是从我拉post提交的信息,而是从切面中获取。

切面中的用户名密码信息是怎么来的呢?我们看到在http handle中有个 check_login_input切面

server.set_http_handler<GET, POST>("/login", &purecpp_controller::login, &purecpp_ctl, check_login_input{});

查看切面(在validate.hpp文件中)

	struct check_login_input {
		bool before(request& req, response& res) {
			auto user_name = req.get_query_value("user_name");
			auto password = req.get_query_value("password");
			if (len_more_than<255>(user_name, password)) {
				res.set_status_and_content(status_type::bad_request, "the input parameter is too long");
				return false;
			}

			if (!check_input(res, user_name, password)) {
				return false;
			}

			req.set_aspect_data(sv2s(user_name), sv2s(password));
			return true;
		}
	};

login在处理前,先进入切面把请求中的user_name和password放入切面中。即然切面中已经有我们post的信息,为什么还是无法登录呢?

我们设置断点,发现,req.get_aspect_data()返回一个vector的引用,vector容器中却有4个成员user_name和password分别在第3和第4个,第1和第2个分别是首页新闻的条数和页数信息,默认的login控制器获取的用户名和密码就变成了新闻页码信息。所以我们把login控制器稍作修改:

		void login(request& req, response& res) {
			//const auto& params = req.get_aspect_data();
			//const auto& user_name = params[0];
			//const auto& password = params[1];
			const auto& user_name = sv2s( req.get_query_value("user_name"));
			const auto& password = sv2s(req.get_query_value("password"));
			
			std::string sql = "select ID, user_role from pp_user where user_login='" + user_name + 
				"' and user_pass=md5('" + password+"')";
			Dao dao;
			auto r = dao.query<std::tuple<std::string, std::string>>(sql);
			if (r.empty()) {
				res.set_status_and_content(status_type::ok, "user name or password is not right");
				return;
			}

			std::string user_id = std::get<0>(r[0]);
			std::string user_role = std::get<1>(r[0]);
			init_session(req, res, user_id, user_role, user_name);

			res.redirect("/home");
		}

这样从request中直接荼取用户名和密码问题 就解决了,点击workdash后跳转到登录页面就能正常登录。

现在修改前端代码,在导航菜单上添加“工作台”

打开我们复制过去的H+代码,导航菜单在navigator.html。

在“社区服务”的html下添加一个:

		<!--  我们添加的workdash工作台 -->
		<li class="layui-nav-item $if category==3 {{layui-this}}">
		<a href= "workdash">工作台</a>

打开workdash中的index.html

在<haad>结点,先把样式表等静态资源地址修改我们自已的目录:

	<link href="./purecpp/workdash/css/bootstrap.min.css?v=3.3.6" rel="stylesheet">
    <link href="./purecpp/workdash/css/font-awesome.min.css?v=4.4.0" rel="stylesheet">
    <link href="./purecpp/workdash/css/animate.css" rel="stylesheet">
    <link href="./purecpp/workdash/css/style.css?v=4.1.0" rel="stylesheet">

用编辑器搜索功能,把所有的图片,js文件的地址都修改完后。我们修改用户名为登录的用户名

<!--
<span class="block m-t-xs"><strong class="font-bold">Beaut-zihan</strong></span>
-->
<span class="block m-t-xs"><strong class="font-bold">${login_user_name}</strong></span>

现在看一下效果,打开主页面:

登录后点击“工作台”(feather数据库默认管理员用户名是tc密码是123456,这边新建一用户xuly)

页面渲染已经正常。

看,是不是很简单?

cinatra语法使用C++17标准,不建议使用原始指针,大量使用智能指针,提高安全性和稳定性,简单的controller可直接用lambda表达式。并且从以上的例子也看到大量使用类型推导,因此开发难度并不比java和php等常用web开发高多少,并且C++直接编译成本地机器语言,性能方面远超其他web框架。

cinatra开源许可证是宽松的MIT许可证,据说新版本已经支持mq和nosql支持,

其他的cinatra和feather的介绍,可参看github上官方的介绍,这里不在赘述。

 

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于C ++ 14/17的HTTP应用程序框架drogon,Drogon可用于使用C ++轻松构建各种类型的Web应用程序服务器程序。 Drogon是一个跨平台框架,它支持Linux,macOS,FreeBSD和Windows。其主要特点如下: *使用基于epoll的非阻塞I / O网络库(macOS / FreeBSD下的kqueue)提供高并发,高性能的网络IO,请访问[TFB测试结果](https://www.techempower。 com / benchmarks /#section = data-r19&hw = ph&test = composite)以获取更多详细信息; *提供完全异步的编程模式; *支持Http1.0 / 1.1(服务器端和客户端); *基于模板,实现了一种简单的反射机制,以完全解耦主程序框架,控制器和视图。 *支持cookie和内置会话; *支持后端渲染,控制器将数据生成到视图以生成Html页面。视图由CSP模板文件描述,C ++代码通过CSP标记嵌入到HTML页面中。 drogon命令行工具会自动生成C ++代码文件进行编译; *支持视图页面动态加载(运行时动态编译和加载); *提供从路径到控制器处理程序的便捷灵活的路由解决方案; *支持过滤器链,以方便在处理HTTP请求之前执行统一的逻辑(例如登录验证,Http方法约束验证等); *支持https(基于OpenSSL); *支持WebSocket(服务器端和客户端); *支持JSON格式的请求和响应,对Restful API应用程序开发非常友好; *支持文件下载和上传; *支持gzip,brotli压缩传输; *支持流水线; *提供轻量级的命令行工具drogon_ctl,以简化Drogon中各种类的创建以及视图代码的生成; *支持基于非阻塞I / O的异步读写数据库(PostgreSQL和MySQL(MariaDB)数据库); *支持基于线程池的异步读写sqlite3数据库; *支持ARM体系结构; *提供方便的轻量级ORM实现,支持常规的对象到数据库双向映射; *支持可在加载时由配置文件安装的插件; *通过内置连接点支持AOP。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值