Skip to content

Commit

Permalink
Consolidate Lanuages To Their Own Folders (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
chuckn408 authored Jun 23, 2024
1 parent 22cf9d2 commit 042c019
Show file tree
Hide file tree
Showing 64 changed files with 471 additions and 471 deletions.
4 changes: 2 additions & 2 deletions CHN-01-概述.md → CHN/CHN-01-概述.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-01-Overview) | [简体中文](CHN-01-概述)
[English](/ENG/ENG-01-Overview) | [简体中文](/CHN/CHN-01-概述)

**Drogon**是一个基于C++17/20的Http应用框架,使用Drogon可以方便的使用C++构建各种类型的Web应用服务端程序。

Expand Down Expand Up @@ -29,4 +29,4 @@ Drogon的主要应用平台是Linux,也支持Mac OS、FreeBSD和Windows。
* 支持插件,可通过配置文件在加载期动态拆装;
* 支持内建插入点的AOP

# 02 [安装drogon](CHN-02-安装)
# 02 [安装drogon](/CHN/CHN-02-安装)
4 changes: 2 additions & 2 deletions CHN-02-安装.md → CHN/CHN-02-安装.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-02-Installation) | [简体中文](CHN-02-安装)
[English](/ENG/ENG-02-Installation) | [简体中文](/CHN/CHN-02-安装)

本节以Ubuntu 18.04, CentOS 7.5, MacOS 12.2为例,简介安装过程,其它系统,大同小异;

Expand Down Expand Up @@ -472,4 +472,4 @@ pip install conan
target_link_libraries(${PROJECT_NAME} PRIVATE drogon)
```
# 03 [快速开始](CHN-03-快速开始)
# 03 [快速开始](/CHN/CHN-03-快速开始)
8 changes: 4 additions & 4 deletions CHN-03-快速开始.md → CHN/CHN-03-快速开始.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-03-Quick-Start) | [简体中文](CHN-03-快速开始)
[English](/ENG/ENG-03-Quick-Start) | [简体中文](/CHN/CHN-03-快速开始)

## 静态网站

Expand All @@ -22,7 +22,7 @@ drogon_ctl create project your_project_name
└── views 存放视图csp文件的目录
```

文件夹的名字就反应了它的用途,用户可以把各类文件(如控制器、过滤器、视图等等)分别放入对应的文件夹,方便项目管理,请读者自行实验。关于`drogon_ctl`的详细使用,可参见[drogon_ctl](CHN-11-drogon_ctl命令)
文件夹的名字就反应了它的用途,用户可以把各类文件(如控制器、过滤器、视图等等)分别放入对应的文件夹,方便项目管理,请读者自行实验。关于`drogon_ctl`的详细使用,可参见[drogon_ctl](/CHN/CHN-11-drogon_ctl命令)

让我们看一下main.cc文件,内容如下:

Expand Down Expand Up @@ -55,7 +55,7 @@ make
echo '<h1>Hello Drogon!</h1>' >>index.html
```

Http根目录默认值是`"./"`, 也就是webapp程序运行的当前路径, Http根目录也可在config.json配置文件中进行更改,可参见[配置文件](CHN-10-配置文件), 然后在地址栏输入`http://localhost``http://localhost/index.html`(或者你的webapp所在服务器的ip)可以访问到这个页面:
Http根目录默认值是`"./"`, 也就是webapp程序运行的当前路径, Http根目录也可在config.json配置文件中进行更改,可参见[配置文件](/CHN/CHN-10-配置文件), 然后在地址栏输入`http://localhost``http://localhost/index.html`(或者你的webapp所在服务器的ip)可以访问到这个页面:
![Hello Drogon!](images/hellodrogon.png)

如果服务器找不到浏览器访问的页面,将返回404页面:
Expand Down Expand Up @@ -190,4 +190,4 @@ make

> **注意: Drogon没有限制控制器(controller)源文件的位置,也可以放在工程目录下,甚至可以在`CMakeLists.txt`中指定到新的目录中,为了方便管理,建议将控制器源文件放在controllers目录。**
# 04.0 [控制器简介](CHN-04-0-控制器-简介)
# 04.0 [控制器简介](/CHN/CHN-04-0-控制器-简介)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-04-0-Controller-Introduction) | [简体中文](CHN-04-控制器-简介)
[English](/ENG/ENG-04-0-Controller-Introduction) | [简体中文](/CHN/CHN-04-控制器-简介)

控制器(controller)在web应用开发中处于相当重要的地位,它处理浏览器发来的请求,然后生成响应发送给浏览器;drogon框架已经帮我们处理好网络传输、Http协议的解析等等细节,我们只需要关注控制器的逻辑即可;每一个控制器对象可以有一个或者多个处理函数(一般称为handler),函数的接口,一般定义成如下形式:

Expand Down Expand Up @@ -33,4 +33,4 @@ public:

注册到drogon框架的控制器最多只会有一个实例,在整个应用运行期间都不会销毁,所以,用户可以在控制器类中声明和使用成员变量。注意,控制器的handler被调用时,是在多线程环境下的(当框架的IO线程数配置成大于1的值时),如果需要访问非临时变量,请做好并发保护工作。

# 04.1 [HttpSimpleController](CHN-04-1-控制器-HttpSimpleController)
# 04.1 [HttpSimpleController](/CHN/CHN-04-1-控制器-HttpSimpleController)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-04-1-Controller-HttpSimpleController) | [简体中文](CHN-04-1-控制器-HttpSimpleController)
[English](/ENG/ENG-04-1-Controller-HttpSimpleController) | [简体中文](/CHN/CHN-04-1-控制器-HttpSimpleController)

可以由`drogon_ctl`命令行工具快速生成基于`HttpSimpleController`的自定义类的源文件,命令格式如下:

Expand Down Expand Up @@ -47,7 +47,7 @@ void TestCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req,
从URL路径到处理函数的路由(或称映射)由宏完成,可以用`PATH_ADD`宏添加多重路径映射,所有`PATH_ADD`语句应夹在`PATH_LIST_BEGIN`和`PATH_LIST_END`宏语句之间。
第一个参数是映射的路径,路径后面的参数是对这个路径的约束,目前支持两种约束,一种是`HttpMethod`类型,表示该路径允许使用的Http方法,可以配置零个或多个,一种是`HttpFilter`类的名字,这种对象执行特定的过滤操作,也可以配置0个或多个,两种类型没有顺序要求,框架会处理好类型的匹配。关于Filter,请参阅[中间件和过滤器](CHN-05-中间件和过滤器)。
第一个参数是映射的路径,路径后面的参数是对这个路径的约束,目前支持两种约束,一种是`HttpMethod`类型,表示该路径允许使用的Http方法,可以配置零个或多个,一种是`HttpFilter`类的名字,这种对象执行特定的过滤操作,也可以配置0个或多个,两种类型没有顺序要求,框架会处理好类型的匹配。关于Filter,请参阅[中间件和过滤器](/CHN/CHN-05-中间件和过滤器)。
用户可以把同一个Simple Controller注册到多个路径上,也可以在同一个路径上注册多个Simple Controller通过 HTTP method 区分)。
Expand All @@ -64,4 +64,4 @@ void TestCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req,

> **上述路径到处理函数的映射是在编译期完成的,事实上,drogon框架也提供了运行期完成映射的接口,运行期映射可以让用户通过配置文件或其它用户接口完成映射或修改映射关系而无需重新编译这个程序(出于性能的考虑,禁止在运行app().run()之后再注册任何映射)。**
# 04.2 [HttpController](CHN-04-2-控制器-HttpController)
# 04.2 [HttpController](/CHN/CHN-04-2-控制器-HttpController)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-04-2-Controller-HttpController) | [简体中文](CHN-04-2-控制器-HttpController)
[English](/ENG/ENG-04-2-Controller-HttpController) | [简体中文](/CHN/CHN-04-2-控制器-HttpController)

### 生成

Expand Down Expand Up @@ -280,4 +280,4 @@ void User::getInfo(const HttpRequestPtr &req,
> **需要注意的是,使用正则表达式要注意匹配冲突(多个不同的handler都匹配),当冲突发生在同一个controller内部时,drogon只会执行第一个handler(先注册进框架的那个handler),当冲突发生在不同controller之间时,执行哪个handler是不确定的,因此用户需要避免这种冲突发生。**
# 04.3 [WebSocketController](CHN-04-3-控制器-WebSocketController)
# 04.3 [WebSocketController](/CHN/CHN-04-3-控制器-WebSocketController)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-04-3-Controller-WebSocketController) | [简体中文](CHN-04-3-控制器-WebSocketController)
[English](/ENG/ENG-04-3-Controller-WebSocketController) | [简体中文](/CHN/CHN-04-3-控制器-WebSocketController)

顾名思义,`WebSocketController`用于处理websocket逻辑。websocket是基于HTTP的一种长连接方案,在websocket建立之初,有一次HTTP格式的请求和应答交换,建立完成后,所有的消息在websocket上传输,消息由固定的格式包装,但消息的内容和收发次序没有任何要求,完全由用户定义。

Expand Down Expand Up @@ -99,7 +99,7 @@ void EchoWebsock::handleConnectionClosed(const WebSocketConnectionPtr &wsConnPtr
}
```
首先,在这个例子中,通过`WS_PATH_ADD`宏把这个控制器注册到了`/echo`路径上,`WS_PATH_ADD`宏的用法跟之前介绍的其他控制器的宏类似,也可以注册路径并且附带若干[中间件和过滤器](CHN-05-中间件和过滤器)。由于websocket在框架中单独处理,所以它可以和前两种控制器的路径重复而不会相互影响。
首先,在这个例子中,通过`WS_PATH_ADD`宏把这个控制器注册到了`/echo`路径上,`WS_PATH_ADD`宏的用法跟之前介绍的其他控制器的宏类似,也可以注册路径并且附带若干[中间件和过滤器](/CHN/CHN-05-中间件和过滤器)。由于websocket在框架中单独处理,所以它可以和前两种控制器的路径重复而不会相互影响。
其次,本例中三个虚函数的实现,只有handleNewMessage有实质内容,只是简单的把收到的消息通过send接口发回客户端。把这个控制器编译进框架,就可以看到效果,请各位自己试验吧。
Expand Down Expand Up @@ -148,4 +148,4 @@ void EchoWebsock::handleConnectionClosed(const WebSocketConnectionPtr &wsConnPtr
any *getMutableContext();
```
# 05 [中间件和过滤器](CHN-05-中间件和过滤器)
# 05 [中间件和过滤器](/CHN/CHN-05-中间件和过滤器)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[English](ENG-05-Middleware-and-Filter) | [简体中文](CHN-05-中间件和过滤器)
[English](/ENG/ENG-05-Middleware-and-Filter) | [简体中文](/CHN/CHN-05-中间件和过滤器)

中间件(middleware)和过滤器(filter)可以帮助用户提高编程效率,在HttpController的[例子](CHN-04-2-控制器-HttpController)中,getInfo方法在返回用户信息之前应该先校验用户是否登录,我们把这个逻辑写在getInfo方法里当然是可以的,但是,很显然,校验用户登录属于通用逻辑,很多接口都将用到,应该把它单独提取出来,再配置到调用handler之前,这就是filter的作用。
中间件(middleware)和过滤器(filter)可以帮助用户提高编程效率,在HttpController的[例子](/CHN/CHN-04-2-控制器-HttpController)中,getInfo方法在返回用户信息之前应该先校验用户是否登录,我们把这个逻辑写在getInfo方法里当然是可以的,但是,很显然,校验用户登录属于通用逻辑,很多接口都将用到,应该把它单独提取出来,再配置到调用handler之前,这就是filter的作用。

drogon的中间件采用了洋葱圈模型, 框架做完URL路径匹配后,会依次调用注册到该路径上的中间件,在每个中间件中,用户可以选择拦截或放行请求,并添加前置、后置处理逻辑。
如果有一个中间件拦截了请求,该请求将不会继续深入洋葱圈内层,对应的handler也不会被调用,但是仍然会通过外层中间件的后置处理逻辑。
Expand Down Expand Up @@ -69,7 +69,7 @@ drogon内置了如下常用过滤器:
};
```

你可以通过 `drogon_ctl` 命令创建过滤器, 见 [drogon_ctl](CHN-11-drogon_ctl命令#过滤器创建).
你可以通过 `drogon_ctl` 命令创建过滤器, 见 [drogon_ctl](/CHN/CHN-11-drogon_ctl命令#过滤器创建).

我们需要重载父类的doFilter虚函数实现过滤器逻辑;

Expand Down Expand Up @@ -98,4 +98,4 @@ drogon内置了如下常用过滤器:
> **注意: 如果中间件/过滤器定义在命名空间里,注册时必须把命名空间写全**
# 06 [视图](CHN-06-视图)
# 06 [视图](/CHN/CHN-06-视图)
4 changes: 2 additions & 2 deletions CHN-06-视图.md → CHN/CHN-06-视图.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-06-View) | [简体中文](CHN-06-视图)
[English](/ENG/ENG-06-View) | [简体中文](/CHN/CHN-06-视图)

### 视图介绍

Expand Down Expand Up @@ -155,4 +155,4 @@ void enableDynamicViewsLoading(const std::vector<std::string> &libPaths);
> **注意: 如果加载时遇到`symbol not found`错误,请使用`cmake .. -DCMAKE_ENABLE_EXPORTS=on`或取消CMakeLists.txt最后一行对`set_property(TARGET ${PROJECT_NAME} PROPERTY ENABLE_EXPORTS ON)`的注释,并重新编译你的工程**
# 07 [会话](CHN-07-会话)
# 07 [会话](/CHN/CHN-07-会话)
4 changes: 2 additions & 2 deletions CHN-07-会话.md → CHN/CHN-07-会话.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-07-Session) | [简体中文](CHN-07-会话)
[English](/ENG/ENG-07-Session) | [简体中文](/CHN/CHN-07-会话)

`会话(Session)`是web应用的重要概念,用于在服务端保存客户端的状态,一般和浏览器的`cookie`配合,drogon提供了对会话的支持。drogon默认**关闭**会话选择,你也可以通过如下接口关闭或打开:

Expand Down Expand Up @@ -97,4 +97,4 @@ drogon::HttpAppFramework::instance().enableSession(1200);
用cmake重新编译整个工程,运行目标程序webapp,就可以通过浏览器看到效果了。
# [数据库](CHN-08-0-数据库-概述)
# [数据库](/CHN/CHN-08-0-数据库-概述)
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[English](ENG-08-0-Database-General) | [简体中文](CHN-08-0-数据库-概述)
[English](/ENG/ENG-08-0-Database-General) | [简体中文](/CHN/CHN-08-0-数据库-概述)

### 概述

**Drogon**内置了数据库读写引擎,对数据库连接的操作基于non-blocking I/O技术实现,因此,从底层到上层接口,都是高效率的非阻塞异步方式,保证了Drogon对高并发性能的追求。目前,Drogon支持PostgreSQL和MySQL数据库,如果要使用数据库,开发系统必须先安装相应数据库的开发环境,Drogon会自动探测这些库的头文件和库文件,编译相应的部分。数据库开发环境的准备,参见[安装数据库环境](CHN-02-安装#数据库环境)
**Drogon**内置了数据库读写引擎,对数据库连接的操作基于non-blocking I/O技术实现,因此,从底层到上层接口,都是高效率的非阻塞异步方式,保证了Drogon对高并发性能的追求。目前,Drogon支持PostgreSQL和MySQL数据库,如果要使用数据库,开发系统必须先安装相应数据库的开发环境,Drogon会自动探测这些库的头文件和库文件,编译相应的部分。数据库开发环境的准备,参见[安装数据库环境](/CHN/CHN-02-安装#数据库环境)

**Drogon**为了支持轻量级应用,也支持sqlite3数据库,通过线程池实现异步接口,与前述数据库的接口是统一的。

Expand All @@ -14,14 +14,14 @@ Drogon的数据库基本操作对象是`DbClient`(这是一个抽象类,用户

通常,一个异步接口调用时,DbClient会在它管理的空闲连接中随机选取一个,执行相关的查询操作,待有结果返回时,`DbClient`会处理数据,通过回调函数对象返回给调用方;如果调用时没有空闲连接,执行内容会被缓存,一旦有连接执行完自己的sql请求,就会从缓存中依次取出待执行的命令去执行。

`DbClient`的详细内容,见[DbClient](CHN-08-1-数据库-DbClient)
`DbClient`的详细内容,见[DbClient](/CHN/CHN-08-1-数据库-DbClient)

### 事务

`DbClient`可以产生事务对象,用以支持事务操作,事务对象除了多出一个`rollback()`接口,其余基本和`DbClient`一致,事务对象的类是`Transaction`,关于事务的详细内容,参见[事务](CHN-08-2-数据库-事务)
`DbClient`可以产生事务对象,用以支持事务操作,事务对象除了多出一个`rollback()`接口,其余基本和`DbClient`一致,事务对象的类是`Transaction`,关于事务的详细内容,参见[事务](/CHN/CHN-08-2-数据库-事务)

### ORM

Drogon也提供了对**ORM**的支持,用户可以通过drogon_ctl读取数据库中的表,并生成对应的model对象类源码,然后,通过`Mapper<MODEL>`类模板完成这些对象的数据库操作,为标准的数据操作提供了简单便捷的接口,使用户可以不用自己写sql语句就可以完成对表的增删改查。关于**ORM**,请参阅[ORM](CHN-08-3-数据库-ORM)
Drogon也提供了对**ORM**的支持,用户可以通过drogon_ctl读取数据库中的表,并生成对应的model对象类源码,然后,通过`Mapper<MODEL>`类模板完成这些对象的数据库操作,为标准的数据操作提供了简单便捷的接口,使用户可以不用自己写sql语句就可以完成对表的增删改查。关于**ORM**,请参阅[ORM](/CHN/CHN-08-3-数据库-ORM)

# 08.1 [DbClient](CHN-08-1-数据库-DbClient)
# 08.1 [DbClient](/CHN/CHN-08-1-数据库-DbClient)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-08-1-Database-DbClient) | [简体中文](CHN-08-1-数据库-DbClient)
[English](/ENG/ENG-08-1-Database-DbClient) | [简体中文](/CHN/CHN-08-1-数据库-DbClient)

### 构建DbClient

Expand All @@ -20,7 +20,7 @@
* 白白的浪费创建连接和断开连接的时间,增加了系统时延;
* 该接口也是非阻塞接口,也就是说,用户拿到DbClient对象时,它管理的连接还没建立起来,框架没有(故意的)提供连接建立成功的回调接口,难道还要sleep一下再开始查询么?这和异步框架的初衷相违背。

所以,应该在程序开始之初就构建这些对象,并在整个生存周期持有并使用它。显然,这个工作完全可以由框架来做,因此,框架提供了第二种构建方式,就是通过配置文件构建或使用createDbClient接口创建,配置方法见[配置文件](CHN-10-配置文件#db_clients数据库客户端)
所以,应该在程序开始之初就构建这些对象,并在整个生存周期持有并使用它。显然,这个工作完全可以由框架来做,因此,框架提供了第二种构建方式,就是通过配置文件构建或使用createDbClient接口创建,配置方法见[配置文件](/CHN/CHN-10-配置文件#db_clients数据库客户端)

需要使用时,通过框架的接口获得DbClient的智能指针,接口如下(注意该接口必须在app.run()调用后才能得到正确的对象):

Expand Down Expand Up @@ -252,4 +252,4 @@ internal::SqlBinder operator<<(const std::string &sql);
它虽然也提供阻塞的接口,这种接口只是阻塞调用者线程,只要调用者线程不是EventLoop线程,就不会影响EventLoop线程的正常运转。回调函数被调用时,回调内的程序是运行在EventLoop线程的,所以,不要在回调内部进行任何阻塞操作,否则会影响数据库的并发,熟悉non-blocking I/O编程的人都应该明白这个约束。
# 08.2 [事务](CHN-08-2-数据库-事务)
# 08.2 [事务](/CHN/CHN-08-2-数据库-事务)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](ENG-08-2-Database-Transaction) | [简体中文](CHN-08-2-数据库-事务)
[English](/ENG/ENG-08-2-Database-Transaction) | [简体中文](/CHN/CHN-08-2-数据库-事务)

> **事务**是关系型数据库的重要特性,Drogon通过`Transaction`类提供了对事务的支持。
Expand Down Expand Up @@ -83,4 +83,4 @@ void newTransactionAsync(const std::function<void(const std::shared_ptr<Transact

本例中使用select for update避免并发修改,update语句在select语句的结果回调中完成,进行了一次嵌套,最外层的大括号是为了限定transPtr的作用范围,使之在执行完sql后及时的销毁从而结束事务。

# 08.3 [ORM](CHN-08-3-数据库-ORM)
# 08.3 [ORM](/CHN/CHN-08-3-数据库-ORM)
Loading

0 comments on commit 042c019

Please sign in to comment.