mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 21:07:26 +02:00
Documentation work
This commit is contained in:
@ -39,8 +39,6 @@ A port handler takes the stream object resulting form an incoming connection
|
||||
request and constructs a handler-specific connection object which provides
|
||||
the desired behavior.
|
||||
|
||||
## Service
|
||||
|
||||
The HTTP ports which come with the example have a system built in which allows
|
||||
installation of framework and user-defined "HTTP services". These services
|
||||
inform connections using the port on how to handle specific requests. This is
|
||||
@ -66,3 +64,74 @@ the HTTP ports:
|
||||
<img width="880" height = "344" alt = "ServerFramework"
|
||||
src="https://raw.githubusercontent.com/vinniefalco/Beast/server/doc/images/server.png">
|
||||
|
||||
## PortHandler Requirements
|
||||
```C++
|
||||
/** An synchronous WebSocket @b PortHandler which implements echo.
|
||||
|
||||
This is a port handler which accepts WebSocket upgrade HTTP
|
||||
requests and implements the echo protocol. All received
|
||||
WebSocket messages will be echoed back to the remote host.
|
||||
*/
|
||||
struct PortHandler
|
||||
{
|
||||
/** Accept a TCP/IP socket.
|
||||
|
||||
This function is called when the server has accepted an
|
||||
incoming connection.
|
||||
|
||||
@param sock The connected socket.
|
||||
|
||||
@param ep The endpoint of the remote host.
|
||||
*/
|
||||
void
|
||||
on_accept(
|
||||
socket_type&& sock,
|
||||
endpoint_type ep);
|
||||
};
|
||||
```
|
||||
|
||||
## Service Requirements
|
||||
|
||||
```C++
|
||||
struct Service
|
||||
{
|
||||
/** Initialize the service
|
||||
|
||||
@param ec Set to the error, if any occurred
|
||||
*/
|
||||
void
|
||||
init(error_code& ec);
|
||||
|
||||
/** Maybe respond to an HTTP request
|
||||
|
||||
Upon handling the response, the service may optionally
|
||||
take ownership of either the stream, the request, or both.
|
||||
|
||||
@param stream The stream representing the connection
|
||||
|
||||
@param ep The remote endpoint of the stream
|
||||
|
||||
@param req The HTTP request
|
||||
|
||||
@param send A function object which operates on a single
|
||||
argument of type beast::http::message. The function object
|
||||
has this equivalent signature:
|
||||
@code
|
||||
template<class Body, class Fields>
|
||||
void send(beast::http::response<Body, Fields>&& res);
|
||||
@endcode
|
||||
|
||||
@return `true` if the service handled the response.
|
||||
*/
|
||||
template<
|
||||
class Stream,
|
||||
class Body, class Fields,
|
||||
class Send>
|
||||
bool
|
||||
respond(
|
||||
Stream&& stream,
|
||||
endpoint_type const& ep,
|
||||
beast::http::request<Body, Fields>&& req,
|
||||
Send const& send) const
|
||||
};
|
||||
```
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
namespace framework {
|
||||
|
||||
// Base class for a type-erased, queued asynchronous HTTP write
|
||||
// Base class for a type-erased, queued asynchronous HTTP write operation
|
||||
//
|
||||
struct queued_http_write
|
||||
{
|
||||
@ -111,7 +111,7 @@ make_queued_http_write(
|
||||
asynchronous calls.
|
||||
|
||||
It uses the Curiously Recurring Template pattern (CRTP) where
|
||||
we refer to the derivd class in order to access the stream object
|
||||
we refer to the derived class in order to access the stream object
|
||||
to use for reading and writing. This lets the same class be used
|
||||
for plain and SSL stream objects.
|
||||
|
||||
@ -492,7 +492,12 @@ class http_async_port
|
||||
service_list<Services...> services_;
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
/** Constructor
|
||||
|
||||
@param instance The server instance which owns this port
|
||||
|
||||
@param log The stream to use for logging
|
||||
*/
|
||||
http_async_port(
|
||||
server& instance,
|
||||
std::ostream& log)
|
||||
|
@ -35,7 +35,7 @@ namespace framework {
|
||||
synchronous calls.
|
||||
|
||||
It uses the Curiously Recurring Template pattern (CRTP) where
|
||||
we refer to the derivd class in order to access the stream object
|
||||
we refer to the derived class in order to access the stream object
|
||||
to use for reading and writing. This lets the same class be used
|
||||
for plain and SSL stream objects.
|
||||
|
||||
@ -45,6 +45,7 @@ template<class Derived, class... Services>
|
||||
class sync_http_con
|
||||
: public http_base
|
||||
{
|
||||
// This function lets us access members of the derived class
|
||||
Derived&
|
||||
impl()
|
||||
{
|
||||
@ -271,6 +272,7 @@ public:
|
||||
}
|
||||
|
||||
// Returns the stream.
|
||||
//
|
||||
// The base class calls this to obtain the object to
|
||||
// use for reading and writing HTTP messages.
|
||||
//
|
||||
@ -297,7 +299,12 @@ class http_sync_port
|
||||
service_list<Services...> services_;
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
/** Constructor
|
||||
|
||||
@param instance The server instance which owns this port
|
||||
|
||||
@param log The stream to use for logging
|
||||
*/
|
||||
http_sync_port(
|
||||
server& instance,
|
||||
std::ostream& log)
|
||||
|
@ -154,6 +154,10 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* This implementation class wraps the PortHandler and
|
||||
manages the listening socket. Upon an incoming connection
|
||||
it transfers ownership of the socket to the PortHandler.
|
||||
*/
|
||||
template<class PortHandler>
|
||||
class port
|
||||
: public std::enable_shared_from_this<
|
||||
@ -228,7 +232,11 @@ private:
|
||||
if(ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
if(! ec)
|
||||
{
|
||||
// Transfer ownership of the socket to the PortHandler
|
||||
//
|
||||
handler_.on_accept(std::move(sock_), ep_);
|
||||
}
|
||||
acceptor_.async_accept(sock_, ep_,
|
||||
std::bind(&port::on_accept, this->shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
|
@ -24,38 +24,6 @@ namespace framework {
|
||||
`true` if the request is processed or `false` if it does not
|
||||
process the request.
|
||||
|
||||
@b Service requirements
|
||||
|
||||
@code
|
||||
|
||||
struct Service
|
||||
{
|
||||
// Initialize the service
|
||||
//
|
||||
void
|
||||
init(error_code& ec);
|
||||
|
||||
// Maybe respond to an HTTP request
|
||||
//
|
||||
// Returns `true` if it handled the response.
|
||||
//
|
||||
// Upon handling the response, the service may optionally
|
||||
// take ownership of either the stream, the request, or both.
|
||||
//
|
||||
template<
|
||||
class Stream,
|
||||
class Body, class Fields,
|
||||
class Send>
|
||||
bool
|
||||
respond(
|
||||
Stream&&,
|
||||
endpoint_type const& ep,
|
||||
beast::http::request<Body, Fields>&& req,
|
||||
Send const& send) const
|
||||
};
|
||||
|
||||
@endcode
|
||||
|
||||
@see file_service, ws_upgrade_service
|
||||
*/
|
||||
template<class... Services>
|
||||
|
@ -35,9 +35,19 @@ template<
|
||||
bool isRequest, class Body, class Fields>
|
||||
class write_msg_op
|
||||
{
|
||||
// This composed operation has a state which is not trivial
|
||||
// to copy (msg) so we need to store the state in an allocated
|
||||
// object.
|
||||
//
|
||||
struct data
|
||||
{
|
||||
// The stream we are writing to
|
||||
AsyncWriteStream& stream;
|
||||
|
||||
// The message we are sending. Note that this composed
|
||||
// operation takes ownership of the message and destroys
|
||||
// it when it is done.
|
||||
//
|
||||
beast::http::message<isRequest, Body, Fields> msg;
|
||||
|
||||
data(
|
||||
@ -50,19 +60,40 @@ class write_msg_op
|
||||
}
|
||||
};
|
||||
|
||||
// `handler_ptr` is a utility which helps to manage a composed
|
||||
// operation's state. It is similar to a shared pointer, but
|
||||
// it uses handler allocation hooks to allocate and free memory,
|
||||
// and it also helps to meet Asio's deallocate-before-invocation
|
||||
// guarantee.
|
||||
//
|
||||
beast::handler_ptr<data, Handler> d_;
|
||||
|
||||
public:
|
||||
// Asio can move and copy the handler, we support both
|
||||
write_msg_op(write_msg_op&&) = default;
|
||||
write_msg_op(write_msg_op const&) = default;
|
||||
|
||||
template<class DeducedHandler, class... Args>
|
||||
write_msg_op(DeducedHandler&& h, AsyncWriteStream& s, Args&&... args)
|
||||
// Constructor
|
||||
//
|
||||
// We take the handler as a template type to
|
||||
// support both const and rvalue references.
|
||||
//
|
||||
template<
|
||||
class DeducedHandler,
|
||||
class... Args>
|
||||
write_msg_op(
|
||||
DeducedHandler&& h,
|
||||
AsyncWriteStream& s,
|
||||
Args&&... args)
|
||||
: d_(std::forward<DeducedHandler>(h),
|
||||
s, std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
// Entry point
|
||||
//
|
||||
// The initiation function calls this to start the operation
|
||||
//
|
||||
void
|
||||
operator()()
|
||||
{
|
||||
@ -71,12 +102,22 @@ public:
|
||||
d.stream, d.msg, std::move(*this));
|
||||
}
|
||||
|
||||
// Completion handler
|
||||
//
|
||||
// This gets called when beast::http::async_write completes
|
||||
//
|
||||
void
|
||||
operator()(error_code ec)
|
||||
{
|
||||
d_.invoke(ec);
|
||||
}
|
||||
|
||||
//
|
||||
// These hooks are necessary for Asio
|
||||
//
|
||||
// The meaning is explained in the Beast documentation
|
||||
//
|
||||
|
||||
friend
|
||||
void* asio_handler_allocate(
|
||||
std::size_t size, write_msg_op* op)
|
||||
|
@ -21,13 +21,11 @@ namespace framework {
|
||||
// This object holds the state of the connection
|
||||
// including, most importantly, the socket or stream.
|
||||
//
|
||||
// `Stream` is the type of socket or stream used as the
|
||||
// transport. Examples include boost::asio::ip::tcp::socket
|
||||
// or `ssl_stream`.
|
||||
//
|
||||
template<class Derived>
|
||||
class async_ws_con
|
||||
{
|
||||
// This function lets us access members of the derived class
|
||||
Derived&
|
||||
impl()
|
||||
{
|
||||
@ -201,12 +199,28 @@ private:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// This class represents an asynchronous WebSocket connection
|
||||
// which uses a plain TCP/IP socket (no encryption) as the stream.
|
||||
//
|
||||
class async_ws_con_plain
|
||||
|
||||
// Note that we give this object the `enable_shared_from_this`, and have
|
||||
// the base class call `impl().shared_from_this()` when needed.
|
||||
//
|
||||
: public std::enable_shared_from_this<async_ws_con_plain>
|
||||
|
||||
// We want the socket to be created before the base class so we use
|
||||
// the "base from member" idiom which Boost provides as a class.
|
||||
//
|
||||
, public base_from_member<beast::websocket::stream<socket_type>>
|
||||
|
||||
// Declare this base last now that everything else got set up first.
|
||||
//
|
||||
, public async_ws_con<async_ws_con_plain>
|
||||
{
|
||||
public:
|
||||
// Construct the plain connection.
|
||||
//
|
||||
template<class... Args>
|
||||
explicit
|
||||
async_ws_con_plain(
|
||||
@ -217,6 +231,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// Returns the stream.
|
||||
//
|
||||
// The base class calls this to obtain the websocket stream object.
|
||||
//
|
||||
beast::websocket::stream<socket_type>&
|
||||
ws()
|
||||
{
|
||||
@ -226,7 +244,7 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** An synchronous WebSocket @b PortHandler which implements echo.
|
||||
/** An asynchronous WebSocket @b PortHandler which implements echo.
|
||||
|
||||
This is a port handler which accepts WebSocket upgrade HTTP
|
||||
requests and implements the echo protocol. All received
|
||||
@ -272,10 +290,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/** Accept a TCP/IP async_ws_con.
|
||||
/** Accept a TCP/IP connection.
|
||||
|
||||
This function is called when the server has accepted an
|
||||
incoming async_ws_con.
|
||||
incoming connection.
|
||||
|
||||
@param sock The connected socket.
|
||||
|
||||
@ -298,10 +316,10 @@ public:
|
||||
|
||||
/** Accept a WebSocket upgrade request.
|
||||
|
||||
This is used to accept a async_ws_con that has already
|
||||
This is used to accept a connection that has already
|
||||
delivered the handshake.
|
||||
|
||||
@param stream The stream corresponding to the async_ws_con.
|
||||
@param stream The stream corresponding to the connection.
|
||||
|
||||
@param ep The remote endpoint.
|
||||
|
||||
@ -310,12 +328,12 @@ public:
|
||||
template<class Body, class Fields>
|
||||
void
|
||||
accept(
|
||||
socket_type&& stream,
|
||||
socket_type&& sock,
|
||||
endpoint_type ep,
|
||||
beast::http::request<Body, Fields>&& req)
|
||||
{
|
||||
std::make_shared<async_ws_con_plain>(
|
||||
std::move(stream),
|
||||
std::move(sock),
|
||||
"ws_async_port",
|
||||
log_,
|
||||
instance_.next_id(),
|
||||
|
@ -19,16 +19,20 @@
|
||||
|
||||
namespace framework {
|
||||
|
||||
// The connection object holds the state of the connection
|
||||
// including, most importantly, the socket or stream.
|
||||
//
|
||||
// `Stream` is the type of socket or stream used as the
|
||||
// transport. Examples include boost::asio::ip::tcp::socket
|
||||
// or `ssl_stream`.
|
||||
//
|
||||
/** A synchronous WebSocket connection.
|
||||
|
||||
This base class implements a WebSocket connection object
|
||||
using synchronous calls.
|
||||
|
||||
It uses the Curiously Recurring Template pattern (CRTP) where
|
||||
we refer to the derived class in order to access the stream object
|
||||
to use for reading and writing. This lets the same class be used
|
||||
for plain and SSL stream objects.
|
||||
*/
|
||||
template<class Derived>
|
||||
class sync_ws_con
|
||||
{
|
||||
// This function lets us access members of the derived class
|
||||
Derived&
|
||||
impl()
|
||||
{
|
||||
@ -237,12 +241,28 @@ private:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// This class represents a synchronous WebSocket connection
|
||||
// which uses a plain TCP/IP socket (no encryption) as the stream.
|
||||
//
|
||||
class sync_ws_con_plain
|
||||
|
||||
// Note that we give this object the `enable_shared_from_this`, and have
|
||||
// the base class call `impl().shared_from_this()` when needed.
|
||||
//
|
||||
: public std::enable_shared_from_this<sync_ws_con_plain>
|
||||
|
||||
// We want the socket to be created before the base class so we use
|
||||
// the "base from member" idiom which Boost provides as a class.
|
||||
//
|
||||
, public base_from_member<beast::websocket::stream<socket_type>>
|
||||
|
||||
// Declare this base last now that everything else got set up first.
|
||||
//
|
||||
, public sync_ws_con<sync_ws_con_plain>
|
||||
{
|
||||
public:
|
||||
// Construct the plain connection.
|
||||
//
|
||||
template<class... Args>
|
||||
explicit
|
||||
sync_ws_con_plain(
|
||||
@ -253,6 +273,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// Returns the stream.
|
||||
//
|
||||
// The base class calls this to obtain the websocket stream object.
|
||||
//
|
||||
beast::websocket::stream<socket_type>&
|
||||
ws()
|
||||
{
|
||||
|
Reference in New Issue
Block a user