将附加参数传递给使用 beast::bind_front_handler 调用的函数
Passing an additional parameter to a function called using beast::bind_front_handler
我有一个boost::beast
REST客户端。 下面给出了.hpp
和.cxx
。
#pragma once
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/strand.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;
// Performs an HTTP GET and prints the response
class RESTClient : public std::enable_shared_from_this<RESTClient> {
public:
explicit RESTClient(net::io_context& ioc);
virtual ~RESTClient();
virtual void run(char const* host, char const* port, char const* target, int version);
virtual void onResolve(beast::error_code ec, tcp::resolver::results_type results);
virtual void onConnect(beast::error_code ec, tcp::resolver::results_type::endpoint_type);
virtual void onWrite(beast::error_code ec, std::size_t bytes_transferred);
virtual void onRead(beast::error_code ec, std::size_t bytes_transferred);
private:
void createGetRequest(char const* host, char const* target, int version);
void createPostRequest(char const* host, char const* target, int version, char const *body);
std::string createBody();
tcp::resolver m_resolver;
beast::tcp_stream m_stream;
beast::flat_buffer m_buffer; // (Must persist between reads)
http::request<http::string_body> m_httpRequest;
http::response<http::string_body> m_httpResponse;
};
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/strand.hpp>
#include <boost/lexical_cast.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include "RESTClient.hpp"
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;
void fail(beast::error_code ec, char const* what) {
std::cerr << what << ": " << ec.message() << "n";
}
RESTClient::RESTClient(net::io_context& ioc)
: m_resolver(net::make_strand(ioc)), m_stream(net::make_strand(ioc)) {
}
RESTClient::~RESTClient() = default;
void RESTClient::run(char const* host, char const* port, char const* target, int version) {
createPostRequest(host, target, version, createBody().c_str());
m_resolver.async_resolve(host, port, beast::bind_front_handler(
&RESTClient::onResolve,
shared_from_this()));
}
void RESTClient::onResolve(beast::error_code ec, tcp::resolver::results_type results) {
if (ec) {
return fail(ec, "resolve");
}
std::cout << "onResolve ******" << std::endl;
m_stream.expires_after(std::chrono::seconds(30));
m_stream.async_connect(results, beast::bind_front_handler(
&RESTClient::onConnect,
shared_from_this()));
}
void
RESTClient::onConnect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) {
if (ec) {
return fail(ec, "connect");
}
std::cout << "onConnect ******" << std::endl;
m_stream.expires_after(std::chrono::seconds(30));
http::async_write(m_stream, m_httpRequest,
beast::bind_front_handler(
&RESTClient::onWrite,
shared_from_this()));
}
void
RESTClient::onWrite(beast::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if (ec) {
return fail(ec, "write");
}
std::cout << "onWrite ******" << std::endl;
http::async_read(m_stream, m_buffer, m_httpResponse, beast::bind_front_handler(
&RESTClient::onRead,
shared_from_this()));
}
void RESTClient::onRead(beast::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if (ec) {
return fail(ec, "read");
}
std::cout << "onRead ******" << std::endl;
std::cout << m_httpResponse << std::endl;
m_stream.socket().shutdown(tcp::socket::shutdown_both, ec);
if (ec && ec != beast::errc::not_connected) {
return fail(ec, "shutdown");
}
}
void RESTClient::createGetRequest(char const* host, char const* target, int version) {
m_httpRequest.version(version);
m_httpRequest.method(http::verb::get);
m_httpRequest.target(target);
m_httpRequest.set(http::field::host, host);
m_httpRequest.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
}
void RESTClient::createPostRequest(char const* host, char const* target, int version, char const* body) {
m_httpRequest.version(version);
m_httpRequest.method(http::verb::post);
m_httpRequest.target(target);
m_httpRequest.set(http::field::host, host);
m_httpRequest.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
m_httpRequest.set(http::field::content_length, boost::lexical_cast<std::string>(strlen(body)));
m_httpRequest.set(http::field::body, body);
m_httpRequest.prepare_payload();
}
std::string RESTClient::createBody() {
boost::property_tree::ptree tree;
boost::property_tree::read_json("test.json",tree);
std::basic_stringstream<char> jsonStream;
boost::property_tree::json_parser::write_json(jsonStream, tree, false);
std::cout << "json stream :" << jsonStream.str() << std::endl;
return jsonStream.str();
}
int main(int argc, char** argv) {
// Check command line arguments.
if (argc != 4 && argc != 5) {
std::cerr <<
"Usage: http-client-async <host> <port> <target> [<HTTP version: 1.0 or 1.1(default)>]n" <<
"Example:n" <<
" http-client-async www.example.com 80 /n" <<
" http-client-async www.example.com 80 / 1.0n";
return EXIT_FAILURE;
}
auto const host = argv[1];
auto const port = argv[2];
auto const target = argv[3];
int version = argc == 5 && !std::strcmp("1.0", argv[4]) ? 10 : 11;
// The io_context is required for all I/O
net::io_context ioc;
std::cout << "version: " << version << std::endl;
// Launch the asynchronous operation
std::make_shared<RESTClient>(ioc)->run(host, port, target, version);
// Run the I/O service. The call will return when
// the get operation is complete.
ioc.run();
return EXIT_SUCCESS;
}
我想在如下所示的行中传递一个std::function<void(bool)>
类型的附加参数以onWrite
。
http::async_write(m_stream, m_httpRequest,
beast::bind_front_handler(
&RESTClient::onWrite,
shared_from_this()));
我该怎么做?
声明:
virtual void onWrite(std::function<void(bool)> f, beast::error_code ec, std::size_t bytes_transferred);
定义:
void
RESTClient::onWrite(std::function<void(bool)> f, beast::error_code ec, std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred);
if (ec) {
return fail(ec, "write");
}
//...
调用:
http::async_write(m_stream, m_httpRequest,
beast::bind_front_handler(
&RESTClient::onWrite,
shared_from_this(),
[](bool){ std::cout << "functor" << std::endl;}
));
相关文章:
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- muQueue.front() 给出了 const 实例,即使我没有将其标记为 const
- 如何实现 Front() 方法以返回模板化双向链表C++的第一个元素?
- boost::bind()类似的东西,但用于函数调用
- 使用 std::应用于 std::bind
- PCL:当我在setConditionFunction中使用std::bind 时,没有合适的转换函数
- std::bind on statd::array 的运算符 []
- std::bind c++ in if statement
- std::bind 是否实现了 std::ref 和 std::cref 来消除函数调用的歧义?
- C++ queue.front();为什么不从第一个元素开始呢?
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 试图克服 std::bind 编译错误
- c++ std::bind within function
- std::bind to void* to std::function
- C++:如何正确地将 deque::front() 返回的变量从函数中传递出去?
- std::bind,无法让具有单个参数的方法工作
- std::bind 和 std::函数术语不值为接受 0 个参数?
- 在调用 std::bind 的产品后意外调用析构函数
- 使用 object 中的方法调用带有 std::bind 和 std::function.target 的 C 样式函数
- 我们应该在使用 std::bind 应用之前检查一个不为空的函数吗?