|
| 1 | +#include <websocketpp/config/asio.hpp> |
| 2 | +#include <websocketpp/server.hpp> |
| 3 | + |
| 4 | +#include <iostream> |
| 5 | + |
| 6 | +// define types for two different server endpoints, one for each config we are |
| 7 | +// using |
| 8 | +typedef websocketpp::server<websocketpp::config::asio> server_plain; |
| 9 | +typedef websocketpp::server<websocketpp::config::asio_tls> server_tls; |
| 10 | + |
| 11 | +// alias some of the bind related functions as they are a bit long |
| 12 | +using websocketpp::lib::placeholders::_1; |
| 13 | +using websocketpp::lib::placeholders::_2; |
| 14 | +using websocketpp::lib::bind; |
| 15 | + |
| 16 | +// type of the ssl context pointer is long so alias it |
| 17 | +typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr; |
| 18 | + |
| 19 | +// The shared on_message handler takes a template parameter so the function can |
| 20 | +// resolve any endpoint dependent types like message_ptr or connection_ptr |
| 21 | +template <typename EndpointType> |
| 22 | +void on_message(EndpointType* s, websocketpp::connection_hdl hdl, |
| 23 | + typename EndpointType::message_ptr msg) |
| 24 | +{ |
| 25 | + std::cout << "on_message called with hdl: " << hdl.lock().get() |
| 26 | + << " and message: " << msg->get_payload() |
| 27 | + << std::endl; |
| 28 | + |
| 29 | + try { |
| 30 | + s->send(hdl, msg->get_payload(), msg->get_opcode()); |
| 31 | + } catch (const websocketpp::lib::error_code& e) { |
| 32 | + std::cout << "Echo failed because: " << e |
| 33 | + << "(" << e.message() << ")" << std::endl; |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +// No change to TLS init methods from echo_server_tls |
| 38 | +std::string get_password() { |
| 39 | + return "test"; |
| 40 | +} |
| 41 | + |
| 42 | +context_ptr on_tls_init(websocketpp::connection_hdl hdl) { |
| 43 | + std::cout << "on_tls_init called with hdl: " << hdl.lock().get() << std::endl; |
| 44 | + context_ptr ctx(new boost::asio::ssl::context(boost::asio::ssl::context::tlsv1)); |
| 45 | + |
| 46 | + try { |
| 47 | + ctx->set_options(boost::asio::ssl::context::default_workarounds | |
| 48 | + boost::asio::ssl::context::no_sslv2 | |
| 49 | + boost::asio::ssl::context::single_dh_use); |
| 50 | + ctx->set_password_callback(bind(&get_password)); |
| 51 | + ctx->use_certificate_chain_file("server.pem"); |
| 52 | + ctx->use_private_key_file("server.pem", boost::asio::ssl::context::pem); |
| 53 | + } catch (std::exception& e) { |
| 54 | + std::cout << e.what() << std::endl; |
| 55 | + } |
| 56 | + return ctx; |
| 57 | +} |
| 58 | + |
| 59 | +int main() { |
| 60 | + // set up an external io_service to run both endpoints on. This is not |
| 61 | + // strictly necessary, but simplifies thread management a bit. |
| 62 | + boost::asio::io_service ios; |
| 63 | + |
| 64 | + // set up plain endpoint |
| 65 | + server_plain endpoint_plain; |
| 66 | + // initialize asio with our external io_service rather than an internal one |
| 67 | + endpoint_plain.init_asio(&ios); |
| 68 | + endpoint_plain.set_message_handler( |
| 69 | + bind(&on_message<server_plain>,&endpoint_plain,::_1,::_2)); |
| 70 | + endpoint_plain.listen(80); |
| 71 | + endpoint_plain.start_accept(); |
| 72 | + |
| 73 | + // set up tls endpoint |
| 74 | + server_tls endpoint_tls; |
| 75 | + endpoint_tls.init_asio(&ios); |
| 76 | + endpoint_tls.set_message_handler( |
| 77 | + bind(&on_message<server_tls>,&endpoint_tls,::_1,::_2)); |
| 78 | + // TLS endpoint has an extra handler for the tls init |
| 79 | + endpoint_tls.set_tls_init_handler(bind(&on_tls_init,::_1)); |
| 80 | + // tls endpoint listens on a different port |
| 81 | + endpoint_tls.listen(443); |
| 82 | + endpoint_tls.start_accept(); |
| 83 | + |
| 84 | + // Start the ASIO io_service run loop running both endpoints |
| 85 | + ios.run(); |
| 86 | +} |
0 commit comments