]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/example/websocket/server/coro/websocket_server_coro.cpp
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 //------------------------------------------------------------------------------
12 // Example: WebSocket server, coroutine
14 //------------------------------------------------------------------------------
16 #include <boost/beast/core.hpp>
17 #include <boost/beast/websocket.hpp>
18 #include <boost/asio/ip/tcp.hpp>
19 #include <boost/asio/spawn.hpp>
29 using tcp
= boost::asio::ip::tcp
; // from <boost/asio/ip/tcp.hpp>
30 namespace websocket
= boost::beast::websocket
; // from <boost/beast/websocket.hpp>
32 //------------------------------------------------------------------------------
36 fail(boost::system::error_code ec
, char const* what
)
38 std::cerr
<< what
<< ": " << ec
.message() << "\n";
41 // Echoes back all received WebSocket messages
43 do_session(tcp::socket
& socket
, boost::asio::yield_context yield
)
45 boost::system::error_code ec
;
47 // Construct the stream by moving in the socket
48 websocket::stream
<tcp::socket
> ws
{std::move(socket
)};
50 // Accept the websocket handshake
51 ws
.async_accept(yield
[ec
]);
53 return fail(ec
, "accept");
57 // This buffer will hold the incoming message
58 boost::beast::multi_buffer buffer
;
61 ws
.async_read(buffer
, yield
[ec
]);
63 // This indicates that the session was closed
64 if(ec
== websocket::error::closed
)
68 return fail(ec
, "read");
70 // Echo the message back
71 ws
.text(ws
.got_text());
72 ws
.async_write(buffer
.data(), yield
[ec
]);
74 return fail(ec
, "write");
78 //------------------------------------------------------------------------------
80 // Accepts incoming connections and launches the sessions
83 boost::asio::io_context
& ioc
,
84 tcp::endpoint endpoint
,
85 boost::asio::yield_context yield
)
87 boost::system::error_code ec
;
90 tcp::acceptor
acceptor(ioc
);
91 acceptor
.open(endpoint
.protocol(), ec
);
93 return fail(ec
, "open");
95 // Bind to the server address
96 acceptor
.bind(endpoint
, ec
);
98 return fail(ec
, "bind");
100 // Start listening for connections
101 acceptor
.listen(boost::asio::socket_base::max_listen_connections
, ec
);
103 return fail(ec
, "listen");
107 tcp::socket
socket(ioc
);
108 acceptor
.async_accept(socket
, yield
[ec
]);
113 acceptor
.get_executor().context(),
117 std::placeholders::_1
));
121 int main(int argc
, char* argv
[])
123 // Check command line arguments.
127 "Usage: websocket-server-coro <address> <port> <threads>\n" <<
129 " websocket-server-coro 0.0.0.0 8080 1\n";
132 auto const address
= boost::asio::ip::make_address(argv
[1]);
133 auto const port
= static_cast<unsigned short>(std::atoi(argv
[2]));
134 auto const threads
= std::max
<int>(1, std::atoi(argv
[3]));
136 // The io_context is required for all I/O
137 boost::asio::io_context ioc
{threads
};
139 // Spawn a listening port
140 boost::asio::spawn(ioc
,
144 tcp::endpoint
{address
, port
},
145 std::placeholders::_1
));
147 // Run the I/O service on the requested number of threads
148 std::vector
<std::thread
> v
;
149 v
.reserve(threads
- 1);
150 for(auto i
= threads
- 1; i
> 0; --i
)