前言
通过前文的内容,以及将基本的PCL的库函数学习完成,但是考虑到系统的存在,并非孤立的,是相互沟通交流的。考虑到当下可移植性,以及便捷性,采用Http的方式进行,进行各模块的沟通
1. 安装
考虑到Http请求库的健壮性以及维护性,选择安装cpprestsdk进行发生Http请求。引入相关的头文件,并且链接相关的库即可安装。
2. post 请求文件
考虑到PCL经过处理后的数据保存为.pcd的点云文件,因此发送http请求,使用发送POST文件请求的形式。首先需要将文件解析成form-data的形式。如下构建文件流的form-data字符串。
const std::string &MultipartParser::GenBodyContent()
{
std::vector<std::future<std::string> > futures;
body_content_.clear();
for(auto &file:files_)
{
std::future<std::string> content_futures = std::async(std::launch::async, [&file]()
{
std::ifstream ifile(file.second, std::ios::binary | std::ios::ate);
std::streamsize size = ifile.tellg();
ifile.seekg(0, std::ios::beg);
char *buff = new char[size];
ifile.read(buff, size);
ifile.close();
std::string ret(buff, size);
delete[] buff;
return ret;
});
futures.push_back(std::move(content_futures));
}
for(auto ¶m:params_)
{
body_content_ += "\r\n--";
body_content_ += boundary_;
body_content_ += "\r\nContent-Disposition: form-data; name=\"";
body_content_ += param.first;
body_content_ += "\"\r\n\r\n";
body_content_ += param.second;
}
for(size_t i = 0; i < files_.size(); ++i)
{
std::string filename;
std::string content_type;
std::string file_content = futures[i].get();
_get_file_name_type(files_[i].second, &filename, &content_type);
body_content_ += "\r\n--";
body_content_ += boundary_;
body_content_ += "\r\nContent-Disposition: form-data; name=\"";
body_content_ += files_[i].first;
body_content_ += "\"; filename=\"";
body_content_ += filename;
body_content_ += "\"\r\nContent-Type: ";
body_content_ += content_type;
body_content_ += "\r\n\r\n";
body_content_ += file_content;
}
body_content_ += "\r\n--";
body_content_ += boundary_;
body_content_ += "--\r\n";
return body_content_;
}
上述代码,首先进行读取文件流,然后将相关的文件进行填充到body_content_字符串里面去,最终得到整个请求文件请求body数据。在构建完成body请求数据后,封装post的文件请求如下:
void post(const std::string& url,const string& file){
try {
MultipartParser parser;
parser.AddFile("file",file);
string boundary = parser.boundary();
string body = parser.GenBodyContent();
LOG(INFO) << "Request Body:" << body;
web::http::http_request request;
web::http::client::http_client client(U(url));
request.set_method(web::http::methods::POST);
request.set_body(body,"multipart/form-data; boundary=" + boundary);
auto result = client.request(request).get();
auto json = result.extract_json().get();
if (json["code"] != 0){
LOG(WARNING) << "Request Error" << json["message"];
return;
}
}catch (std::exception& e){
LOG(WARNING) << "Request Occur Error:" << e.what();
}
}
上述即一个完整的POST文件请求,将请求的文件发送到远程服务器上。
GET请求
同理,构建相关的get请求如下
void get(const std::string& url,const absl::flat_hash_map<string,web::json::value>& param,web::json::value &result){
try {
web::http::http_request request;
web::http::client::http_client client(U(url));
web::http::uri_builder builder;
std::for_each(param.begin(), param.end(), [&](const std::pair<string,web::json::value> &item) {
builder.append_query(item.first,item.second);
});
auto response = client.request(web::http::methods::GET,builder.to_string()).get();
auto json = response.extract_json().get();
if (json["code"] != 0){
LOG(WARNING) << "Request Error" << json["message"];
return;
}
std::swap(result,json["data"]);
}catch (std::exception &e){
LOG(WARNING) << "Request Occur Error:" << e.what();
}
}
上述完成相关发生GET请求到服务器上。
总结
本文结束相关cpprestsdk发送http请求,方便与外界系统进行相应的数据交流,打破数据孤岛的存在