【lesson7】服务端业务处理模块实现

文章目录

  • 业务处理实现思路
  • 业务处理类设计
    • 成员变量
    • 成员函数
      • RunModule
      • upLoad
      • listShow
      • downLoad
      • getETagInfo

业务处理实现思路

云备份项目中 ,业务处理模块是针对客户端的业务请求进行处理,并最终给与响应。而整个过程中包含以下要实现的功能:

  • 借助网络通信模块httplib库搭建http服务器与客户端进行网络通信
  • 针对收到的请求进行对应的业务处理并进行响应(文件上传,列表查看,文件下载(包含断点续传))

业务处理类设计

成员变量

private:
    int _server_port;//服务端端口
    std::string _server_ip;//服务端ip
    std::string _download_prefix;//下载前缀
    static std::string _back_dir;//备份文件
    httplib::Server _server;//创建server对象,用于搭建服务器

成员函数

private:
	static void upLoad(const httplib::Request& rq, const httplib::Response& rp)//上传请求,上传数据到服务器
    {}
    static std::string timeToString(time_t t)//返回一个年月日格式的字符类型时间
    {
        return std::ctime(&t);
    }
    static void listShow(const httplib::Request& rq, httplib::Response& rp)//响应数据到客户端浏览器
    {}
    static std::string getETagInfo(const BackupInfo& info)//获取ETag信息
    {}
    static void downLoad(const httplib::Request& rq, httplib::Response& rp)//下载请求,下载数据到客户端
    {}
public:
    serevr()
    {
    	//初始化一些数据
        Config* cnf = Config::getIstance();
        _server_port = cnf->getServerPort();
        _server_ip = cnf->getServerIp();
        _download_prefix = cnf->getDownloadPrefix();
        _back_dir = cnf->getBackDir();
    }
    bool RunModule()//运行模块
    {}

RunModule

HTTP文件上传请求格式:

POST /upload HTTP/1.1
Content-Length:11
Content-Type:multipart/form-data;boundary= ----WebKitFormBoundary+16字节随机字符
------WebKitFormBoundary
Content-Disposition:form-data;filename="a.txt";
hello world
------WebKitFormBoundary--

响应:

HTTP/1.1 200 OK
Content-Length: 0

HTTP文件列表获取请求格式:

GET /list HTTP/1.1
Content-Length: 0

响应:

HTTP/1.1 200 OK
Content-Length:
Content-Type: text/html
<html>
 <head>
   	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 	<title>Page of Download</title>
 </head>
 <body>
 	<h1>Download</h1>
 	<table>
 		<tr>
   			<td><a href="/download/a.txt"> a.txt </a></td>
   			<td align="right"> 1994-07-08 03:00 </td>
   			<td align="right"> 27K </td>
 		</tr>
 	</table>
 </body>
</html>

HTTP文件下载请求格式:

GET /download/a.txt http/1.1
Content-Length: 0

响应:

HTTP/1.1 200 OK
Content-Length: 100000
ETags: "filename-size-mtime一个能够唯一标识文件的数据"
Accept-Ranges: bytes//告诉客户端支持断点续传

HTTP断点续传:

GET /download/a.txt http/1.1
Content-Length: 0
If-Range: "文件唯一标识"
Range: bytes=89-999

响应:

HTTP/1.1 206 Partial Content
Content-Length:
Content-Range: bytes 89-999/100000
Content-Type: application/octet-stream
ETag: "inode-size-mtime一个能够唯一标识文件的数据"
Accept-Ranges: bytes
对应文件从89999字节的数据
bool RunModule()
{
    _server.Post("/upload",upLoad);//处理上传文件请求
    _server.Get("/listshow", listShow);//处理展示页面请求
    _server.Get("/", listShow);//处理展示页面请求
    std::string url = _download_prefix + "(.*)";
    _server.Get(url,downLoad);//处理下载请求
    _server.listen("0.0.0.0", _server_port);//监听所有
    //上面Post/Get的第二个参数全是回调函数, 业务处理逻辑将在其中进行

    return true;
}

upLoad

static void upLoad(const httplib::Request& rq, const httplib::Response& rp)
{
	//1.判断是否有"file"字段, 这个字段是我们自己设置的
    bool ret = rq.has_file("file");
    if(ret == false)
    {
        return ;
    }
	
	//2.获取file字段的所有内容
    const auto& file = rq.get_file_value("file");
    std::string real_path = _back_dir + fileUtil(file.filename).fileName();
    //3.将file字段里的content内容写入到real_path文件中
    fileUtil fu(real_path);
    fu.setContent(file.content);
	
	//4.创建文件信息,并管理起来
    BackupInfo info;
    info.NewBackupInfo(real_path);
    _data->insert(info);
    return;

}

listShow

返回一个HTML页面
效果如图所示
在这里插入图片描述

static void listShow(const httplib::Request& rq, httplib::Response& rp)
{
	//1.获取所有文件信息
    std::vector<BackupInfo> arry;
    _data->getAll(&arry);
    //2.构建HTML响应
    std::stringstream ss;
    ss << "<html><head><title>Download</title></head>";
    ss << " <body><h1>Download</h1><table>";
    for(auto& e : arry)
    {
        ss << "<tr>";

        std::string filename = fileUtil(e.real_path).fileName();
        ss << "<td><a href='" << e.url << "'>" << filename << "</a></td>";

        ss << "<td align='right'>";
        ss << timeToString(e.modify_time);
        ss << "</td>";

        ss << "<td align='right'>";
        ss << e.file_size / 1024 << "K";
        ss << "</td>";

        ss << "</tr>";
    }
    ss << "</table></body></html>";
    rp.body = ss.str();
    rp.set_header("Content-Type", "text/html");
    rp.status = 200;

}

downLoad

static void downLoad(const httplib::Request& rq, httplib::Response& rp)
{
	//1.获取url
    std::string url = rq.path;
    //std::cout << url << std::endl;
    //2.通过url获取文件信息
    BackupInfo info;
    _data->getBifoByUrl(url, &info);
    //std::cout << info.real_path << std::endl;
	
	//3.判断是否是压缩文件
    if(info.pack_flag == true)
    {
        //解压文件
        fileUtil fu(info.pack_path);
        fu.uncompress(info.real_path);
        
        //删除压缩文件, 并修改BackupInfo信息
        fu.Remove();
        info.pack_flag = false;
        _data->insert(info);
    }

    // if(rq.has_header("If-Range"))
    //     std::cout << "hello" << std::endl;
    // else
    //     std::cout << "no" << std::endl;
    // for(auto& e : rp.headers)
    // {
    //     std::cout << e.second << std::endl;
    // }
    
	//4.获取文件内容,并设置响应内容
    fileUtil fu(info.real_path);
    fu.getContent(&rp.body);
    //Accept-Ranges 告诉客户端服务器支持断点续传
    rp.set_header("Accept-Ranges", "bytes");
    rp.set_header("ETag", getETagInfo(info));
    rp.set_header("Content-Type", "application/octet-stream");
    //rp.status = 200;
	
	//判断是否有If-Range字段,并且If-Range字段的ETag内容和getETagInfo(info)的ETag内容一样
    if(rq.has_header("If-Range") && rq.get_header_value("If-Range") == getETagInfo(info))
    {
    	//206 断点续传
        rp.status = 206;
        //std::cout << rp.status << std::endl;
    }
    else
    {
    	//200响应全文
        rp.status = 200;
    }
}

getETagInfo

//服务器自己设计的唯一标识格式
static std::string getETagInfo(const BackupInfo& info)
{
    std::string etag;
    etag += fileUtil(info.real_path).fileName();
    etag += "-";
    etag += std::to_string(info.file_size);
    etag += "-";
    etag += std::to_string(info.modify_time);

    return etag;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/700246.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

这所大学25考研计算机学院专业课已全面改考为408!南京信息工程大学计算机考研!

南京信息工程大学&#xff08;Nanjing University of Information Science and Technology&#xff09;&#xff0c;简称“南信大”&#xff0c;位于江苏省南京市&#xff0c;是一所以大气科学为特色的全国重点大学&#xff0c;由江苏省人民政府、中华人民共和国教育部、中国气…

【lesson1】第三方库(jsoncpp,bundle, httplib)的介绍和使用

文章目录 jsoncpp库json 认识jsoncpp 认识jsoncpp 实现序列化jsoncpp 实现反序列化 bundle库bundle库实现文件压缩bundle库实现文件解压缩 httplib 库httplib 库搭建简单服务器httplib库搭建简单客户端 jsoncpp库 json 认识 json 是一种数据交换格式&#xff0c;采用完全独立…

OS进程取样器OS Process Sampler执行CMD/Shell命令

Apache JMeter - Users Manual: Component Reference 1.背景 项目上最近需要测试一种很少用到的DICOM协议,但是网上资料很少,基本上可以总结为三种方案: 直接发送TCP 16进制数据包,但是参数化数据准备难度大通过开发封装jar包发送,需要开发组提供通过发送cmd命令给前置机…

ES升级--05--快照生成 和备份

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 备份ES数据1.关闭集群自动均衡2.执行同步刷新3.停止集群节点的Elasticsearch服务4.修改Elasticsearch配置文件&#xff0c;开启快照功能&#xff0c;配置仓库目录为…

java:FeignClient通过RequestInterceptor自动添加header

示例代码 【pom.xml】 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.12.RELEASE</version> </dependency> <dependency><groupId>o…

f-stack和DPDK

GPT-4 (OpenAI) f-stack和DPDK&#xff08;数据平面开发套件&#xff09;都是与高性能网络处理相关的技术。它们的目的是提高数据包的处理速度&#xff0c;优化网络I/O的性能。以下是对这两者的简要解释&#xff1a; 1. **DPDK (Data Plane Development Kit):** DPDK 是一个…

柯桥成人外语培训|职场商务英语剑桥国际英语口语外贸商务英语

01 “puppy love”是什么意思&#xff1f; 大家都知道&#xff0c;puppy有“幼犬&#xff0c;小狗”的意思&#xff0c;love是“爱”&#xff0c;那puppy love是什么意思呢&#xff1f;可不是字面上表达的小狗的爱哦&#xff01; 其实&#xff0c;"puppy love"真正的…

轻松实现App推广代理结算,Xinstall超级渠道功能助您一臂之力!

在App推广的广阔天地中&#xff0c;与渠道方建立合作关系&#xff0c;共同实现用户增长和品牌提升&#xff0c;已成为众多开发者和广告主的共识。然而&#xff0c;如何高效管理这些渠道、监测推广效果、实现代理结算&#xff0c;一直是困扰大家的难题。今天&#xff0c;我们就来…

P4. 微服务: 匹配系统(上)

P4. 微服务: 匹配系统 上 Tips0 概述1 匹配系统流程2 游戏系统流程3 websocket 前后端通信的基础配置3.1 websocket 的需要的配置3.2 websocket 连接的建立3.3 为 websocket 连接添加 jwt 验证 4 实现匹配界面和对战界面的切换5 匹配系统的客户端和 websocket 后端交互部分5.1 …

Spark的开发环境配置

1. 介绍 这里主要记录一下&#xff0c;我们常用的maven配置&#xff0c;方便后期开发配置环境&#xff0c;避免每次都从零开始配置工程。 2. 工程目录 3. pom的配置 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven…

Leetcode学习

回文数 反转一半数字 第一个想法是将数字转换为字符串&#xff0c;并检查字符串是否为回文。 但是&#xff0c;这需要额外的非常量空间来创建问题描述中所不允许的字符串。 第二个想法是将数字本身反转&#xff0c;然后将反转的数字与原始数字比较&#xff0c;如果它们是相同…

【课程总结】Day6(下):机器学习项目实战–成人收入预测

机器学习项目实战&#xff1a;成人收入预测 项目目的 基于个人收入数据(包括教育程度、年龄、性别等)的数据集&#xff0c;通过机器学习算法&#xff0c;预测一个人的年收入是否超过5万美金。 数据集 地址&#xff1a;http://idatascience.cn/dataset-detail?table_id10036…

HJS-DE1/3断电延时时间继电器 导轨安装 约瑟JOSEF

​HJS-DE断电延时时间继电器 HJS-DE1/3断电延时时间继电器 HJS-DE1/2断电延时时间继电器 HJS-DE断电延时时间继电器 用途 时间继电器HJS-DE1/3作为通电立即动作断电延时返回的元件&#xff0c;用于交流或直流保护和自动控制装置中&#xff0c;使被控元件得到所需延时。本继电…

MySQL系列-语法说明以及基本操作(一)

1、前言 主要讲解MySQL的基本语法 官网文档 https://docs.oracle.com/en-us/iaas/mysql-database/doc/getting-started.html 关于MySQL的基本语法&#xff0c;关于数据类型、表的操作、数据操作、事务、备份等&#xff0c;可参考 http://www.voidme.com/mysql 2、数据类型 数…

【PX4-AutoPilot教程-TIPS】离线安装Flight Review PX4日志分析工具

离线安装Flight Review PX4日志分析工具 安装方法 安装方法 使用Flight Review在线分析日志&#xff0c;有时会因为网络原因无法使用。 使用离线安装的方式使用Flight Review&#xff0c;可以在无需网络的情况下使用Flight Review网页。 安装环境依赖。 sudo apt-get insta…

在客户自己的smarteye server上如何测试使用公网对讲PoC集群通话功能

创建用户对讲群组&#xff0c;可以在WEB调度台上操作&#xff0c;也可以在执法记录仪或者手机上操作&#xff0c;当然&#xff0c;前提是当前登录的用户有创建集群通话对讲组的权限&#xff0c;一般的推荐用管理员帐号去创建这些对讲组&#xff0c;这样最简单。 总体说明 用管…

echarts的toolbox自定义feature标签及事件

1. 需求 在使用echarts图时希望toolbox扩展一些自定义icon和点击事件&#xff0c;而不只是图中这些echarts提供的事件。 2. 文档 属性名类型描述toolbox.featureObject各工具配置项。 feature中除了echarts提供的各个内置的工具按钮外&#xff0c;可以自定义工具按钮。 除…

经典文献阅读之--FlashOcc(快速且内存高效的占用预测模块)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

windows下编译linux的go程序报错gcc_linux_amd64.c: In function ‘_cgo_sys_thread_start‘:

报错解决 执行报错 报错解决 其他补充 windows下编译linux 64位程序 set GOARCHamd64 set GOOSlinux set CGO_ENABLED0 go build手把手教你实现Golang跨平台编译 报错解决其他补充windows下编译linux 64位程序Windows下编译Mac平台64位可执行程序&#xff1a;Linux 下编译…

webpack--压缩,代码的拆分,tree shinking

Terser 对代码进行压缩、丑化 const TerserPlugin require("terser-webpack-plugin");optimization: { minimize: true, //在开发环境下启用 CSS 优化minimizer: [new TerserPlugin({extractComments: false,terserOptions: {compress: {arguments: true,// 将函数…