‹  返回课程

Web Server 版 “Hello world”

课文
阅读量:477
技术范畴
从经典C++“Hello world”,到将问候输出到用户浏览器的Web Server版“Hello world”,变化是什么?注意,还将学习到C++11新标中,使用lambda表达式表示动作。
课前导言
从经典C++“Hello world”,到将问候输出到用户浏览器的Web Server版“Hello world”,变化是什么?注意,还将学习到C++11新标中,使用lambda表达式表示动作。
Web Server 版 “Hello world”
基于大器框架,快速写出可向浏览器返回“Hello world”的Web后端。

1. 从经典版 Hello world开始

这是典型的C++入门第一课的“Hello world”代码:

#include iostream

using nampespace std;

int main()
{    
    cout << "Hello world!" << endl;    
    
    return 0;
}

约十行代码,运行后只能往控制台上输出一行问候。

将它修改为“大器/da4qi4”框架搭建的 Web Server 版本的“Hello world”,代码为:

#include "daqi/da4qi4.hpp"

using namespace da4qi4;

int main()
{    
    auto svc = Server::Supply("127.0.0.1", 4098);    
    svc->Run();    

    return 0;
}

约11行代码,我们创建了一个空转的,似乎不干活的Web Server。虽然被污蔑为不干活,但其实个Web Server是在正常运行中,它之所以表现成不干活,只是因为它要忠于创建它的主人,也就是我们(程序员):我们没有指示它如何响应,所以它对所有的请求,都只能回应一句:”Not Found“,没错,就是著名的404响应。

编译、运行,然后在浏览器地址栏输入:http://127.0.0.1:4098 ,而后回车,浏览器将显示一个页面,上面写着:

我们创建了一个空转的,似乎不干活的Web Server。虽然被污蔑为不干活,但其实个Web Server是在正常运行中,它之所以表现成不干活,只是因为它要忠于创建它的主人,也就是我们(程序员):我们没有指示它如何响应,所以它对所有的请求,都只能回应一句:”Not Found“,没错,就是著名的404响应。

小提示:代码中的”Supply(4098)“如果不提供”4098“这个入参,那么启动后的Web Server将在HTTP默认的80端口监听。我们使用4098是考虑到在许多程序员的开发电脑上,80端口可能已经被别的应用占用了。

main函数中的两行代码,简单说说:

  1. Server是大器框架提供的一个类,对应一个用于提供网站内容的服务(Web Server)。这个类有一个静态方法叫”Supply “,中文是”提供、供应“之意。
  2. Server类有一个(非静态的)方法,叫”Run()“,”svc->Run()“就是让刚创建的Web Server对象运行起来。

好吧,真正需要说的,或许是这一段:这个Web Server程序运行起来之后,要如何退出啊?很简单,也很常见:在控制中按下Ctrl+C组合键即可。大器框架将收到该信号,然后安全退出。

3. Hello World!

不管访问什么都回我们一句”Not Found“这仅人沮丧。接下我们希望,当访问网站的根路径时,它能答应一声:”Hello World!“。

3.1 针对指定URL的响应

这需要我们通过代码指示 ”大器 Web 框架“ 作为动作。首先演示使用普通函数来表示动作:

#include "daqi/da4qi4.hpp"

using namespace da4qi4;

void hello(Context ctx)
{    
    ctx->Res().ReplyOk("Hello World!");    
    ctx->Pass();     
}

int main()
{    
    auto svc = Server::Supply("127.0.0.1", 4098);    
    svc->AddHandler(_GET_, "/", hello);    
    svc->Run();
    
    return 0;
}

hello函数的返回值必须是void,而入参是Context,它是大器框架定义用的,用来表示当前正在进行中的一次来自客户的浏览器的访问。通过调用它的Res()得到用来表达对这次访问的回复“response”。

接着将同样功能改为使用C++11引入的lambda实现:

#include "daqi/da4qi4.hpp"

using namespace da4qi4;

int main()
{    
    auto svc = Server::Supply(4098);    
    svc->AddHandler(_GET_, "/", [](Context ctx)    
    {        
        ctx->Res().ReplyOk("Hello World!");        
        ctx->Pass();    
    });    
    
    svc->Run();
}

例中使用到的Server类的AddHandler()方法,并提供三个入参:

  1. 指定的HTTP访问方法: _GET_;
  2. 指定的访问URL: /,即根路径 ;
  3. 匿名的lambda表达式。

三个入参以及方法名,表达一个意思:如果用户以GET方法访问网站的根路径,框架就调用lambda 表达式以做出响应。

编译、运行。现在用浏览器访问 http://127.0.0.1:4098 ,将看到提:

Hello World!

下一节课,我们演示如何合理向前端(浏览器)返回标准的HTML页面。

课后补充
不要小看“Hello world”,更不要小看Web Server 版本的“Hello world”,它帮我们封装了至少包括:网络服务端、HTTP协议解析、并发响应等复杂的工作。让我们得以轻松的专注于具体业务的实现。