summaryrefslogtreecommitdiffstats
path: root/websocketpp/roles/server_endpoint.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'websocketpp/roles/server_endpoint.hpp')
-rw-r--r--websocketpp/roles/server_endpoint.hpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/websocketpp/roles/server_endpoint.hpp b/websocketpp/roles/server_endpoint.hpp
new file mode 100644
index 00000000..d76eea8a
--- /dev/null
+++ b/websocketpp/roles/server_endpoint.hpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2014, Peter Thorson. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the WebSocket++ Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WEBSOCKETPP_SERVER_ENDPOINT_HPP
+#define WEBSOCKETPP_SERVER_ENDPOINT_HPP
+
+#include <websocketpp/endpoint.hpp>
+
+#include <websocketpp/logger/levels.hpp>
+
+#include <websocketpp/common/system_error.hpp>
+
+namespace websocketpp {
+
+/// Server endpoint role based on the given config
+/**
+ *
+ */
+template <typename config>
+class server : public endpoint<connection<config>,config> {
+public:
+ /// Type of this endpoint
+ typedef server<config> type;
+
+ /// Type of the endpoint concurrency component
+ typedef typename config::concurrency_type concurrency_type;
+ /// Type of the endpoint transport component
+ typedef typename config::transport_type transport_type;
+
+ /// Type of the connections this server will create
+ typedef connection<config> connection_type;
+ /// Type of a shared pointer to the connections this server will create
+ typedef typename connection_type::ptr connection_ptr;
+
+ /// Type of the connection transport component
+ typedef typename transport_type::transport_con_type transport_con_type;
+ /// Type of a shared pointer to the connection transport component
+ typedef typename transport_con_type::ptr transport_con_ptr;
+
+ /// Type of the endpoint component of this server
+ typedef endpoint<connection_type,config> endpoint_type;
+
+ friend class connection<config>;
+
+ explicit server() : endpoint_type(true)
+ {
+ endpoint_type::m_alog.write(log::alevel::devel, "server constructor");
+ }
+
+ /// Destructor
+ ~server<config>() {}
+
+#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
+ // no copy constructor because endpoints are not copyable
+ server<config>(server<config> &) = delete;
+
+ // no copy assignment operator because endpoints are not copyable
+ server<config> & operator=(server<config> const &) = delete;
+#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
+
+#ifdef _WEBSOCKETPP_MOVE_SEMANTICS_
+ /// Move constructor
+ server<config>(server<config> && o) : endpoint<connection<config>,config>(std::move(o)) {}
+
+#ifdef _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
+ // no move assignment operator because of const member variables
+ server<config> & operator=(server<config> &&) = delete;
+#endif // _WEBSOCKETPP_DEFAULT_DELETE_FUNCTIONS_
+
+#endif // _WEBSOCKETPP_MOVE_SEMANTICS_
+
+ /// Create and initialize a new connection
+ /**
+ * The connection will be initialized and ready to begin. Call its start()
+ * method to begin the processing loop.
+ *
+ * Note: The connection must either be started or terminated using
+ * connection::terminate in order to avoid memory leaks.
+ *
+ * @return A pointer to the new connection.
+ */
+ connection_ptr get_connection() {
+ return endpoint_type::create_connection();
+ }
+
+ /// Starts the server's async connection acceptance loop (exception free)
+ /**
+ * Initiates the server connection acceptance loop. Must be called after
+ * listen. This method will have no effect until the underlying io_service
+ * starts running. It may be called after the io_service is already running.
+ *
+ * Refer to documentation for the transport policy you are using for
+ * instructions on how to stop this acceptance loop.
+ *
+ * @param [out] ec A status code indicating an error, if any.
+ */
+ void start_accept(lib::error_code & ec) {
+ if (!transport_type::is_listening()) {
+ ec = error::make_error_code(error::async_accept_not_listening);
+ return;
+ }
+
+ ec = lib::error_code();
+ connection_ptr con = get_connection();
+
+ transport_type::async_accept(
+ lib::static_pointer_cast<transport_con_type>(con),
+ lib::bind(&type::handle_accept,this,con,lib::placeholders::_1),
+ ec
+ );
+
+ if (ec && con) {
+ // If the connection was constructed but the accept failed,
+ // terminate the connection to prevent memory leaks
+ con->terminate(lib::error_code());
+ }
+ }
+
+ /// Starts the server's async connection acceptance loop
+ /**
+ * Initiates the server connection acceptance loop. Must be called after
+ * listen. This method will have no effect until the underlying io_service
+ * starts running. It may be called after the io_service is already running.
+ *
+ * Refer to documentation for the transport policy you are using for
+ * instructions on how to stop this acceptance loop.
+ */
+ void start_accept() {
+ lib::error_code ec;
+ start_accept(ec);
+ if (ec) {
+ throw exception(ec);
+ }
+ }
+
+ /// Handler callback for start_accept
+ void handle_accept(connection_ptr con, lib::error_code const & ec) {
+ if (ec) {
+ con->terminate(ec);
+
+ if (ec == error::operation_canceled) {
+ endpoint_type::m_elog.write(log::elevel::info,
+ "handle_accept error: "+ec.message());
+ } else {
+ endpoint_type::m_elog.write(log::elevel::rerror,
+ "handle_accept error: "+ec.message());
+ }
+ } else {
+ con->start();
+ }
+
+ lib::error_code start_ec;
+ start_accept(start_ec);
+ if (start_ec == error::async_accept_not_listening) {
+ endpoint_type::m_elog.write(log::elevel::info,
+ "Stopping acceptance of new connections because the underlying transport is no longer listening.");
+ } else if (start_ec) {
+ endpoint_type::m_elog.write(log::elevel::rerror,
+ "Restarting async_accept loop failed: "+ec.message());
+ }
+ }
+};
+
+} // namespace websocketpp
+
+#endif //WEBSOCKETPP_SERVER_ENDPOINT_HPP