client_endpoint.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright (c) 2014, Peter Thorson. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above copyright
  9. * notice, this list of conditions and the following disclaimer in the
  10. * documentation and/or other materials provided with the distribution.
  11. * * Neither the name of the WebSocket++ Project nor the
  12. * names of its contributors may be used to endorse or promote products
  13. * derived from this software without specific prior written permission.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
  19. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. *
  26. */
  27. #ifndef WEBSOCKETPP_CLIENT_ENDPOINT_HPP
  28. #define WEBSOCKETPP_CLIENT_ENDPOINT_HPP
  29. #include <websocketpp/endpoint.hpp>
  30. #include <websocketpp/uri.hpp>
  31. #include <websocketpp/logger/levels.hpp>
  32. #include <websocketpp/common/system_error.hpp>
  33. #include <string>
  34. namespace websocketpp {
  35. /// Client endpoint role based on the given config
  36. /**
  37. *
  38. */
  39. template <typename config>
  40. class client : public endpoint<connection<config>,config> {
  41. public:
  42. /// Type of this endpoint
  43. typedef client<config> type;
  44. /// Type of the endpoint concurrency component
  45. typedef typename config::concurrency_type concurrency_type;
  46. /// Type of the endpoint transport component
  47. typedef typename config::transport_type transport_type;
  48. /// Type of the connections this server will create
  49. typedef connection<config> connection_type;
  50. /// Type of a shared pointer to the connections this server will create
  51. typedef typename connection_type::ptr connection_ptr;
  52. /// Type of the connection transport component
  53. typedef typename transport_type::transport_con_type transport_con_type;
  54. /// Type of a shared pointer to the connection transport component
  55. typedef typename transport_con_type::ptr transport_con_ptr;
  56. /// Type of the endpoint component of this server
  57. typedef endpoint<connection_type,config> endpoint_type;
  58. friend class connection<config>;
  59. explicit client() : endpoint_type(false)
  60. {
  61. endpoint_type::m_alog->write(log::alevel::devel, "client constructor");
  62. }
  63. /// Get a new connection
  64. /**
  65. * Creates and returns a pointer to a new connection to the given URI
  66. * suitable for passing to connect(connection_ptr). This method allows
  67. * applying connection specific settings before performing the opening
  68. * handshake.
  69. *
  70. * @param [in] location URI to open the connection to as a uri_ptr
  71. * @param [out] ec An status code indicating failure reasons, if any
  72. *
  73. * @return A connection_ptr to the new connection
  74. */
  75. connection_ptr get_connection(uri_ptr location, lib::error_code & ec) {
  76. if (location->get_secure() && !transport_type::is_secure()) {
  77. ec = error::make_error_code(error::endpoint_not_secure);
  78. return connection_ptr();
  79. }
  80. connection_ptr con = endpoint_type::create_connection();
  81. if (!con) {
  82. ec = error::make_error_code(error::con_creation_failed);
  83. return con;
  84. }
  85. con->set_uri(location);
  86. ec = lib::error_code();
  87. return con;
  88. }
  89. /// Get a new connection (string version)
  90. /**
  91. * Creates and returns a pointer to a new connection to the given URI
  92. * suitable for passing to connect(connection_ptr). This overload allows
  93. * default construction of the uri_ptr from a standard string.
  94. *
  95. * @param [in] u URI to open the connection to as a string
  96. * @param [out] ec An status code indicating failure reasons, if any
  97. *
  98. * @return A connection_ptr to the new connection
  99. */
  100. connection_ptr get_connection(std::string const & u, lib::error_code & ec) {
  101. uri_ptr location = lib::make_shared<uri>(u);
  102. if (!location->get_valid()) {
  103. ec = error::make_error_code(error::invalid_uri);
  104. return connection_ptr();
  105. }
  106. return get_connection(location, ec);
  107. }
  108. /// Begin the connection process for the given connection
  109. /**
  110. * Initiates the opening connection handshake for connection con. Exact
  111. * behavior depends on the underlying transport policy.
  112. *
  113. * @param con The connection to connect
  114. *
  115. * @return The pointer to the connection originally passed in.
  116. */
  117. connection_ptr connect(connection_ptr con) {
  118. // Ask transport to perform a connection
  119. transport_type::async_connect(
  120. lib::static_pointer_cast<transport_con_type>(con),
  121. con->get_uri(),
  122. lib::bind(
  123. &type::handle_connect,
  124. this,
  125. con,
  126. lib::placeholders::_1
  127. )
  128. );
  129. return con;
  130. }
  131. private:
  132. // handle_connect
  133. void handle_connect(connection_ptr con, lib::error_code const & ec) {
  134. if (ec) {
  135. con->terminate(ec);
  136. endpoint_type::m_elog->write(log::elevel::rerror,
  137. "handle_connect error: "+ec.message());
  138. } else {
  139. endpoint_type::m_alog->write(log::alevel::connect,
  140. "Successful connection");
  141. con->start();
  142. }
  143. }
  144. };
  145. } // namespace websocketpp
  146. #endif //WEBSOCKETPP_CLIENT_ENDPOINT_HPP