workflow系列教程(6)实现静态资源服务器

这篇具有很好参考价值的文章主要介绍了workflow系列教程(6)实现静态资源服务器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

往期教程

如果觉得写的可以,请给一个点赞+关注支持一下

观看之前请先看,往期的博客教程,否则这篇博客没办法看懂

  • workFlow c++异步网络库编译教程与简介

  • C++异步网络库workflow入门教程(1)HTTP任务

  • C++异步网络库workflow系列教程(2)redis任务

  • workflow系列教程(3)Series串联任务流

  • workflow系列教程(4)Parallel并联任务流

  • workflow系列教程(5-1)HTTP Server

  • workflow系列教程(5-2)实现HTTP反向代理

处理请求

我们不占用任何线程读取文件,而是产生一个异步的读文件任务,在读取完成之后回复请求。
再次说明一下,我们需要把完整回复数据读取到内存,才开始回复消息。所以不适合用来传输太大的文件。

struct SeriesContext{
    WFHttpTask *serverTask;	//所属workflow任务
    int fd;					//文件fd
    char *buf;				//文件数据缓冲区
    size_t filesize;		//文件大小
};

void process(WFHttpTask *serverTask){
    // 1 创建文件IO任务
    size_t filesize = 614;
    int fd = open("postform.html",O_RDONLY);
    char *buf = new char[filesize];
    auto IOTask = WFTaskFactory::create_pread_task(fd,buf,filesize,0,IOCallback);
    // 2 把文件IO任务加入到序列中
    series_of(serverTask)->push_back(IOTask);
    // 3 创建传递给IOTask的context
    SeriesContext *context = new SeriesContext;
    context->serverTask =  serverTask;
    context->fd = fd;
    context->buf = buf;
    context->filesize = filesize;
    series_of(serverTask)->set_context(context);
    // 4 设置序列的回调函数,释放所有资源
    series_of(serverTask)->set_callback([](const SeriesWork *series){
        fprintf(stderr,"series callback\n");
        SeriesContext * context = static_cast<SeriesContext *>(series->get_context());
        delete[] context->buf;
        close(context->fd);
        delete context;
    });
}

与HTTP反向代理产生一个新的http client任务不同,这里我们通过factory产生了一个pread任务。
在WFTaskFactory.h里,我们可以看到相关的接口。

struct FileIOArgs
{
    int fd;
    void *buf;
    size_t count;
    off_t offset;
};

...
using WFFileIOTask = WFFileTask<struct FileIOArgs>;
using fio_callback_t = std::function<void (WFFileIOTask *)>;
...

class WFTaskFactory
{
public:
    ...
    static WFFileIOTask *create_pread_task(int fd, void *buf, size_t count, off_t offset,
                                           fio_callback_t callback);

    static WFFileIOTask *create_pwrite_task(int fd, void *buf, size_t count, off_t offset,
                                            fio_callback_t callback);
    ...

    /* Interface with file path name */
	static WFFileIOTask *create_pread_task(const std::string& pathname, void *buf, size_t count, off_t offset,
                                           fio_callback_t callback);

    static WFFileIOTask *create_pwrite_task(const std::string& pathname, void *buf, size_t count, off_t offset,
                                            fio_callback_t callback);  
};

无论是pread还是pwrite,返回的都是WFFileIOTask。这与不区分sort或psort,不区分client或server task是一个道理。
除这两个接口还有preadv和pwritev,返回WFFileVIOTask,以及fsync,fdsync,返回WFFileSyncTask。可以在头文件里查看。
示例用了task的user_data域保存服务的全局数据。但对于大服务,推荐使用series context。

处理读文件结果及响应

将文件资源返回给客户端

void IOCallback(WFFileIOTask *IOTask){
    SeriesContext *context = static_cast<SeriesContext *>(series_of(IOTask)->get_context());
    auto resp2client = context->serverTask->get_resp();
    resp2client->add_header_pair("Content-Type","text/html");
    resp2client->append_output_body(context->buf,context->filesize);
}

完整代码

postform.html文章来源地址https://www.toymoban.com/news/detail-849516.html

<!DOCTYPE html>
<html>
    <head>
        <title>test</title>
    </head>
    <body> 
        <form  method="post" enctype="application/x-www-form-urlencoded">
            <div>
              <label for="username">username:</label>
              <input type="text" name="username">
            </div>
            <div>
              <label for="password">password:</label>
              <input type="text" name="password">
            </div>
            <div class="button">
                <button type="submit">Send your message</button>
            </div>
        </form>
    </body>
</html>
#include "linuxheader.h"
#include <workflow/WFFacilities.h>
#include <workflow/WFHttpServer.h>
#include <workflow/HttpUtil.h>
static WFFacilities::WaitGroup waitGroup(1);
void sigHandler(int num){
    waitGroup.done();
    fprintf(stderr,"wait group is done\n");
}
struct SeriesContext{
    WFHttpTask *serverTask;
    int fd;
    char *buf;
    size_t filesize;
};
void IOCallback(WFFileIOTask *IOTask){
    SeriesContext *context = static_cast<SeriesContext *>(series_of(IOTask)->get_context());
    auto resp2client = context->serverTask->get_resp();
    resp2client->add_header_pair("Content-Type","text/html");
    resp2client->append_output_body(context->buf,context->filesize);
}
void process(WFHttpTask *serverTask){
    // 1 创建文件IO任务
    size_t filesize = 614;
    int fd = open("postform.html",O_RDONLY);
    char *buf = new char[filesize];
    auto IOTask = WFTaskFactory::create_pread_task(fd,buf,filesize,0,IOCallback);
    // 2 把文件IO任务加入到序列中
    series_of(serverTask)->push_back(IOTask);
    // 3 创建传递给IOTask的context
    SeriesContext *context = new SeriesContext;
    context->serverTask =  serverTask;
    context->fd = fd;
    context->buf = buf;
    context->filesize = filesize;
    series_of(serverTask)->set_context(context);
    // 4 设置序列的回调函数,释放所有资源
    series_of(serverTask)->set_callback([](const SeriesWork *series){
        fprintf(stderr,"series callback\n");
        SeriesContext * context = static_cast<SeriesContext *>(series->get_context());
        delete[] context->buf;
        close(context->fd);
        delete context;
    });
}
int main(){
    signal(SIGINT,sigHandler);
    WFHttpServer server(process);
    if(server.start(1234) == 0){
        waitGroup.wait();
        server.stop();
    }
    else{
        perror("server start failed\n");
        return -1;
    }
    return 0;   
}

到了这里,关于workflow系列教程(6)实现静态资源服务器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Nginx与Tomcat的区别,什么是HTTP服务器(处理静态资源的服务器),什么是处理动态资源的服务器

    Nginx和Tomcat都是常用的Web服务器,但它们的主要作用不同。 Nginx是一个HTTP服务器,反向代理服务器和通用TCP/UDP代理服务器。 它通常用于静态内容、媒体流和负载均衡。在高流量和高并发负载下,Nginx表现更出色,并且能够轻松处理静态文件、压缩和SSL/TLS卸载等任务,以减轻

    2024年02月14日
    浏览(37)
  • Linux服务器远程访问通过Tomcat部署的静态资源

    1.1 安装Java 下载jdk8 切换到root用户,创建文件夹/usr/local/java,将下载的jdk压缩包上传到该目录下,解压 编辑配置文件,配置环境变量,在末尾添加如下内容 重载激活配置 检查安装成功 1.2 安装Tomcat 下载tomcat 切换到root用户,创建文件夹/usr/local/tomcat,将下载的tomcat压缩包上传

    2024年01月18日
    浏览(66)
  • Nginx 配置一级和二级证书以及作为静态资源服务器

    卷挂载中的 ssl 证书替换为自己 ssl 证书的位置。 关于 nginx *.conf 配置文件不过多描述! 在同一个 default.conf 文件中写 server 就可以。 只作为简单静态资源服务器!

    2024年01月18日
    浏览(52)
  • Springboot 使用thymeleaf 服务器无法加载resources中的静态资源异常处理

    Springboot使用thymeleaf,并 连接远程数据库 启动时,无法加载resources中的静态资源 浏览器报错 后端启动时报错 前端打开页面时后端报错 打包编译项目,显示找不到js、css、html等静态资源,但本地路径并没有写错,于是我去找编译文件,查看是不是静态资源没有编译到,打开项

    2024年02月04日
    浏览(47)
  • Windows 环境下nginx 静态资源服务器(图片,文件)权限控制(nginx/openresty/lua)

    1 同nginx配置server以后,我们可以很方便的直接访问到文件服务器上的文件资源,但是某些情况下,文件资源可能是隐私图片,比如客户注册时上传的身份证照片等等,这时候我们需要对图片访问进行控制,必须登录后才能查看到这些隐私图片。 2 一般来说,我们都是通过后端

    2024年02月09日
    浏览(55)
  • 关于前端vue打包项目以及静态网站部署项目到阿里云ECS云服务器初学简单教程

    准备工作: 1.首先进入https://ecs.console.aliyun.com/ 领取或者购买一台简单的ECS云服务器。 进入网站注册登录后拉到页面最下面或者顶部搜索免费云服务器领取立即试用 ,当然富哥花钱买一台服务器也行。   创建完了以后可以进入云服务ECS工作台,然后就是以下界面   点击右边

    2024年02月04日
    浏览(67)
  • python自带静态web服务器搭建代码实现(一)

    一、静态web服务器 静态web法服务器: 可为发出请求的浏览器提供静态文档的程序,平时上网浏览的页面都是动态的,而开发的是静态的,页面数据不会发生变化 搭建python自带的静态web服务器 命令: python3 -m http.server 端口号 -m: 表示运行包里面的模块,执行该命令需进入指

    2024年02月03日
    浏览(50)
  • 如何异地链接Pycharm服务器进行远程开发并实现与公司服务器资源同步

    本文主要介绍如何使用Pycharm进行远程开发,并实现在家远程与公司服务器资源同步。 新版本 Jetbrains 系列开发IDE( IntelliJ IDEA , PyCharm , GoLand )等都支持远程使用服务器编译,并且可以 通过SFTP同步本地与服务器项目代码 。 这样做的好处是**我们只要连接上服务器就能开始

    2024年02月01日
    浏览(61)
  • vue3项目服务器静态文件部署增加指定路由地址完整实现

    在 Vue 3 项目中,如果你想要配置服务器以便让它在特定的地址上运行,你通常是在使用 Vue CLI 的 devServer 配置。这主要是通过修改 vue.config.js 文件实现的。 如果你希望开发服务器绑定到特定地址,比如 192.168.1.100 ,可以这样做: 在项目根目录下创建或修改 vue.config.js : 如果你

    2024年02月07日
    浏览(42)
  • 如何使用Pycharm进行远程开发,并实现在家远程与公司服务器资源同步

    本文主要介绍如何使用Pycharm进行远程开发,并实现在家远程与公司服务器资源同步。 新版本 Jetbrains 系列开发IDE( IntelliJ IDEA , PyCharm , GoLand )等都支持远程使用服务器编译,并且可以 通过SFTP同步本地与服务器项目代码 。 这样做的好处是**我们只要连接上服务器就能开始

    2024年02月04日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包