]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/example/websocket/server/coro-ssl/websocket_server_coro_ssl.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 SSL server, coroutine
14 //------------------------------------------------------------------------------
16 #include "example/common/server_certificate.hpp"
18 #include <boost/beast/core.hpp>
19 #include <boost/beast/websocket.hpp>
20 #include <boost/beast/websocket/ssl.hpp>
21 #include <boost/asio/ip/tcp.hpp>
22 #include <boost/asio/spawn.hpp>
23 #include <boost/asio/ssl/stream.hpp>
33 using tcp
= boost::asio::ip::tcp
; // from <boost/asio/ip/tcp.hpp>
34 namespace ssl
= boost::asio::ssl
; // from <boost/asio/ssl.hpp>
35 namespace websocket
= boost::beast::websocket
; // from <boost/beast/websocket.hpp>
37 //------------------------------------------------------------------------------
41 fail(boost::system::error_code ec
, char const* what
)
43 std::cerr
<< what
<< ": " << ec
.message() << "\n";
46 // Echoes back all received WebSocket messages
51 boost::asio::yield_context yield
)
53 boost::system::error_code ec
;
55 // Construct the stream by moving in the socket
56 websocket::stream
<ssl::stream
<tcp::socket
&>> ws
{socket
, ctx
};
58 // Perform the SSL handshake
59 ws
.next_layer().async_handshake(ssl::stream_base::server
, yield
[ec
]);
61 return fail(ec
, "handshake");
63 // Accept the websocket handshake
64 ws
.async_accept(yield
[ec
]);
66 return fail(ec
, "accept");
70 // This buffer will hold the incoming message
71 boost::beast::multi_buffer buffer
;
74 ws
.async_read(buffer
, yield
[ec
]);
76 // This indicates that the session was closed
77 if(ec
== websocket::error::closed
)
81 return fail(ec
, "read");
83 // Echo the message back
84 ws
.text(ws
.got_text());
85 ws
.async_write(buffer
.data(), yield
[ec
]);
87 return fail(ec
, "write");
91 //------------------------------------------------------------------------------
93 // Accepts incoming connections and launches the sessions
96 boost::asio::io_context
& ioc
,
98 tcp::endpoint endpoint
,
99 boost::asio::yield_context yield
)
101 boost::system::error_code ec
;
104 tcp::acceptor
acceptor(ioc
);
105 acceptor
.open(endpoint
.protocol(), ec
);
107 return fail(ec
, "open");
109 // Bind to the server address
110 acceptor
.bind(endpoint
, ec
);
112 return fail(ec
, "bind");
114 // Start listening for connections
115 acceptor
.listen(boost::asio::socket_base::max_listen_connections
, ec
);
117 return fail(ec
, "listen");
121 tcp::socket
socket(ioc
);
122 acceptor
.async_accept(socket
, yield
[ec
]);
127 acceptor
.get_executor().context(),
132 std::placeholders::_1
));
136 int main(int argc
, char* argv
[])
138 // Check command line arguments.
142 "Usage: websocket-server-coro-ssl <address> <port> <threads>\n" <<
144 " websocket-server-coro-ssl 0.0.0.0 8080 1\n";
147 auto const address
= boost::asio::ip::make_address(argv
[1]);
148 auto const port
= static_cast<unsigned short>(std::atoi(argv
[2]));
149 auto const threads
= std::max
<int>(1, std::atoi(argv
[3]));
151 // The io_context is required for all I/O
152 boost::asio::io_context ioc
{threads
};
154 // The SSL context is required, and holds certificates
155 ssl::context ctx
{ssl::context::sslv23
};
157 // This holds the self-signed certificate used by the server
158 load_server_certificate(ctx
);
160 // Spawn a listening port
161 boost::asio::spawn(ioc
,
166 tcp::endpoint
{address
, port
},
167 std::placeholders::_1
));
169 // Run the I/O service on the requested number of threads
170 std::vector
<std::thread
> v
;
171 v
.reserve(threads
- 1);
172 for(auto i
= threads
- 1; i
> 0; --i
)