如何将读取处理程序传递给 Beast websocket 的 async_read?
How to pass read handler to async_read for Beast websocket?
如何将回调传递给 async_read
?我尝试了以下但它不会
编译。我基于修改 docs
中的代码
#include <beast/core.hpp>
#include <beast/http.hpp>
#include <beast/version.hpp>
#include <boost/asio.hpp>
#include <beast/websocket.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
using tcp = boost::asio::ip::tcp;
namespace http = beast::http;
namespace websocket = beast::websocket;
beast::multi_buffer buffer_;
void read_handler(
const boost::system::error_code& ec,
std::size_t bytes_transferred) {
std::cout << "READ" << std::endl;
std::cout << beast::buffers(buffer_.data()) << std::endl;
if(ec) {
std::cout << "error in read " << ec.message() << std::endl;
}
}
int main() {
boost::asio::io_service ios;
tcp::socket sock{ios};
beast::error_code ec;
websocket::stream<tcp::socket&> ws{sock};
beast::multi_buffer buffer;
ws.async_read(buffer_, boost::bind(&read_handler,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
));
return 0;
}
In file included from /usr/local/include/boost/bind.hpp:22:0,
from test.cpp:6:
/usr/local/include/boost/bind/bind.hpp: In instantiation of ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = void (*)(const boost::system::error_code&, long unsigned int); A = boost::_bi::rrlist1<const boost::system::error_code&>; A1 = boost::arg<1> (*)(); A2 = boost::arg<2> (*)()]’:
/usr/local/include/boost/bind/bind.hpp:1306:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = const boost::system::error_code&; R = void; F = void (*)(const boost::system::error_code&, long unsigned int); L = boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()>; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/cc/workspace/Beast/include/beast/websocket/impl/read.ipp:1085:5: required from ‘void beast::websocket::stream<NextLayer>::read_op<DynamicBuffer, Handler>::operator()(const error_code&, bool) [with DynamicBuffer = beast::basic_multi_buffer<std::allocator<char> >; Handler = boost::_bi::bind_t<void, void (*)(const boost::system::error_code&, long unsigned int), boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()> >; NextLayer = boost::asio::basic_stream_socket<boost::asio::ip::tcp>&; beast::error_code = boost::system::error_code]’
/home/cc/workspace/Beast/include/beast/websocket/impl/read.ipp:1104:26: required from ‘beast::async_return_type<ReadHandler, void(boost::system::error_code)> beast::websocket::stream<NextLayer>::async_read(DynamicBuffer&, ReadHandler&&) [with DynamicBuffer = beast::basic_multi_buffer<std::allocator<char> >; ReadHandler = boost::_bi::bind_t<void, void (*)(const boost::system::error_code&, long unsigned int), boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()> >; NextLayer = boost::asio::basic_stream_socket<boost::asio::ip::tcp>&; beast::async_return_type<ReadHandler, void(boost::system::error_code)> = void]’
test.cpp:39:6: required from here
/usr/local/include/boost/bind/bind.hpp:319:56: error: invalid conversion from ‘boost::arg<2> (*)()’ to ‘boost::arg<1> (*)()’ [-fpermissive]
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
^
/usr/local/include/boost/bind/bind.hpp:882:11: error: initializing argument 1 of ‘A1&& boost::_bi::rrlist1<A1>::operator[](boost::arg<1> (*)()) const [with A1 = const boost::system::error_code&]’ [-fpermissive]
A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
^
/usr/local/include/boost/bind/bind.hpp:319:34: error: invalid user-defined conversion from ‘const boost::system::error_code’ to ‘long unsigned int’ [-fpermissive]
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
^
我做了上述不使用 boost::bind
的更改,它对我有用。我还使用 boost/beast
而不是 beast
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
using tcp = boost::asio::ip::tcp;
namespace http = boost::beast::http;
namespace websocket = boost::beast::websocket;
boost::beast::multi_buffer buffer_;
void read_handler(
const boost::system::error_code& ec,
std::size_t bytes_transferred) {
std::cout << "READ" << std::endl;
std::cout << boost::beast::buffers(buffer_.data()) << std::endl;
if(ec) {
std::cout << "error in read " << ec.message() << std::endl;
}
}
int main() {
boost::asio::io_service ios;
tcp::socket sock{ios};
boost::beast::error_code ec;
websocket::stream<tcp::socket&> ws{sock};
boost::beast::multi_buffer buffer;
ws.async_read(buffer_, &read_handler);
// ws.async_read(buffer_, boost::bind(&read_handler,
// boost::asio::placeholders::error,
// boost::asio::placeholders::bytes_transferred
// ));
return 0;
}
这是为我编译的,使用下面
$ g++ -std=gnu++11 -I/usr/include -I/usr/local/include test.cpp -L/usr/local/lib -L/usr/lib -L/lib/x86_64-linux-gnu/ -lboost_system -lpthread
由于链接器错误,我无法生成可执行文件,但我认为您可以轻松处理
Edit-1:使用 Beast 获得 Boost 的步骤
我使用 Vagrant bento/ubuntu-16.04
框测试了这些步骤。
sudo apt update
sudo apt install -y g++ gcc make
wget https://dl.bintray.com/boostorg/release/1.65.1/source/boost_1_65_1.tar.gz
tar xf boost_1_65_1.tar.gz
cd boost_1_65_1/
sh bootstrap.sh
pushd libs
mv asio asio.old
git clone https://github.com/boostorg/asio asio
git clone https://github.com/boostorg/beast.git
popd
./b2 cxxflags="-std=c++11"
./b2 cxxflags="-std=c++11" headers
sudo ./b2 cxxflags="-std=c++11" install
添加 beast 和 asio 后应该会有所提升
如何将回调传递给 async_read
?我尝试了以下但它不会
编译。我基于修改 docs
#include <beast/core.hpp>
#include <beast/http.hpp>
#include <beast/version.hpp>
#include <boost/asio.hpp>
#include <beast/websocket.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
using tcp = boost::asio::ip::tcp;
namespace http = beast::http;
namespace websocket = beast::websocket;
beast::multi_buffer buffer_;
void read_handler(
const boost::system::error_code& ec,
std::size_t bytes_transferred) {
std::cout << "READ" << std::endl;
std::cout << beast::buffers(buffer_.data()) << std::endl;
if(ec) {
std::cout << "error in read " << ec.message() << std::endl;
}
}
int main() {
boost::asio::io_service ios;
tcp::socket sock{ios};
beast::error_code ec;
websocket::stream<tcp::socket&> ws{sock};
beast::multi_buffer buffer;
ws.async_read(buffer_, boost::bind(&read_handler,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
));
return 0;
}
In file included from /usr/local/include/boost/bind.hpp:22:0,
from test.cpp:6:
/usr/local/include/boost/bind/bind.hpp: In instantiation of ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = void (*)(const boost::system::error_code&, long unsigned int); A = boost::_bi::rrlist1<const boost::system::error_code&>; A1 = boost::arg<1> (*)(); A2 = boost::arg<2> (*)()]’:
/usr/local/include/boost/bind/bind.hpp:1306:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = const boost::system::error_code&; R = void; F = void (*)(const boost::system::error_code&, long unsigned int); L = boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()>; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/cc/workspace/Beast/include/beast/websocket/impl/read.ipp:1085:5: required from ‘void beast::websocket::stream<NextLayer>::read_op<DynamicBuffer, Handler>::operator()(const error_code&, bool) [with DynamicBuffer = beast::basic_multi_buffer<std::allocator<char> >; Handler = boost::_bi::bind_t<void, void (*)(const boost::system::error_code&, long unsigned int), boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()> >; NextLayer = boost::asio::basic_stream_socket<boost::asio::ip::tcp>&; beast::error_code = boost::system::error_code]’
/home/cc/workspace/Beast/include/beast/websocket/impl/read.ipp:1104:26: required from ‘beast::async_return_type<ReadHandler, void(boost::system::error_code)> beast::websocket::stream<NextLayer>::async_read(DynamicBuffer&, ReadHandler&&) [with DynamicBuffer = beast::basic_multi_buffer<std::allocator<char> >; ReadHandler = boost::_bi::bind_t<void, void (*)(const boost::system::error_code&, long unsigned int), boost::_bi::list2<boost::arg<1> (*)(), boost::arg<2> (*)()> >; NextLayer = boost::asio::basic_stream_socket<boost::asio::ip::tcp>&; beast::async_return_type<ReadHandler, void(boost::system::error_code)> = void]’
test.cpp:39:6: required from here
/usr/local/include/boost/bind/bind.hpp:319:56: error: invalid conversion from ‘boost::arg<2> (*)()’ to ‘boost::arg<1> (*)()’ [-fpermissive]
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
^
/usr/local/include/boost/bind/bind.hpp:882:11: error: initializing argument 1 of ‘A1&& boost::_bi::rrlist1<A1>::operator[](boost::arg<1> (*)()) const [with A1 = const boost::system::error_code&]’ [-fpermissive]
A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
^
/usr/local/include/boost/bind/bind.hpp:319:34: error: invalid user-defined conversion from ‘const boost::system::error_code’ to ‘long unsigned int’ [-fpermissive]
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
^
我做了上述不使用 boost::bind
的更改,它对我有用。我还使用 boost/beast
而不是 beast
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
using tcp = boost::asio::ip::tcp;
namespace http = boost::beast::http;
namespace websocket = boost::beast::websocket;
boost::beast::multi_buffer buffer_;
void read_handler(
const boost::system::error_code& ec,
std::size_t bytes_transferred) {
std::cout << "READ" << std::endl;
std::cout << boost::beast::buffers(buffer_.data()) << std::endl;
if(ec) {
std::cout << "error in read " << ec.message() << std::endl;
}
}
int main() {
boost::asio::io_service ios;
tcp::socket sock{ios};
boost::beast::error_code ec;
websocket::stream<tcp::socket&> ws{sock};
boost::beast::multi_buffer buffer;
ws.async_read(buffer_, &read_handler);
// ws.async_read(buffer_, boost::bind(&read_handler,
// boost::asio::placeholders::error,
// boost::asio::placeholders::bytes_transferred
// ));
return 0;
}
这是为我编译的,使用下面
$ g++ -std=gnu++11 -I/usr/include -I/usr/local/include test.cpp -L/usr/local/lib -L/usr/lib -L/lib/x86_64-linux-gnu/ -lboost_system -lpthread
由于链接器错误,我无法生成可执行文件,但我认为您可以轻松处理
Edit-1:使用 Beast 获得 Boost 的步骤
我使用 Vagrant bento/ubuntu-16.04
框测试了这些步骤。
sudo apt update
sudo apt install -y g++ gcc make
wget https://dl.bintray.com/boostorg/release/1.65.1/source/boost_1_65_1.tar.gz
tar xf boost_1_65_1.tar.gz
cd boost_1_65_1/
sh bootstrap.sh
pushd libs
mv asio asio.old
git clone https://github.com/boostorg/asio asio
git clone https://github.com/boostorg/beast.git
popd
./b2 cxxflags="-std=c++11"
./b2 cxxflags="-std=c++11" headers
sudo ./b2 cxxflags="-std=c++11" install
添加 beast 和 asio 后应该会有所提升