diff --git a/src/ripple_app/websocket/WSConnection.h b/src/ripple_app/websocket/WSConnection.h index b56a7e604..b323d4e43 100644 --- a/src/ripple_app/websocket/WSConnection.h +++ b/src/ripple_app/websocket/WSConnection.h @@ -160,10 +160,8 @@ public: bool onPingTimer (std::string&) { -#ifdef DISCONNECT_ON_WEBSOCKET_PING_TIMEOUTS if (m_sentPing) return true; // causes connection to close -#endif m_sentPing = true; setPingTimer (); diff --git a/src/ripple_app/websocket/WSDoor.cpp b/src/ripple_app/websocket/WSDoor.cpp index a55e54fc2..3ff490fb4 100644 --- a/src/ripple_app/websocket/WSDoor.cpp +++ b/src/ripple_app/websocket/WSDoor.cpp @@ -74,7 +74,7 @@ private: { ScopedLockType lock (m_endpointLock, __FILE__, __LINE__); - m_endpoint = new websocketpp::server_multitls (handler); + m_endpoint = boost::make_shared (handler); } // Call the main-event-loop of the websocket server. @@ -107,7 +107,7 @@ private: { ScopedLockType lock (m_endpointLock, __FILE__, __LINE__); - m_endpoint = nullptr; + m_endpoint.reset(); } stopped (); @@ -115,16 +115,20 @@ private: void onStop () { + boost::shared_ptr endpoint; + { ScopedLockType lock (m_endpointLock, __FILE__, __LINE__); - // VFALCO NOTE we probably dont want to block here - // but websocketpp is deficient and broken. - // - if (m_endpoint != nullptr) - m_endpoint->stop (); + endpoint = m_endpoint; } + // VFALCO NOTE we probably dont want to block here + // but websocketpp is deficient and broken. + // + if (endpoint) + endpoint->stop (); + signalThreadShouldExit (); } @@ -137,7 +141,7 @@ private: boost::asio::ssl::context& m_ssl_context; LockType m_endpointLock; - ScopedPointer m_endpoint; + boost::shared_ptr m_endpoint; bool mPublic; bool mProxy; std::string mIp; diff --git a/src/ripple_app/websocket/WSServerHandler.h b/src/ripple_app/websocket/WSServerHandler.h index 69ff01d9d..88fb21d62 100644 --- a/src/ripple_app/websocket/WSServerHandler.h +++ b/src/ripple_app/websocket/WSServerHandler.h @@ -69,8 +69,9 @@ private: protected: // For each connection maintain an associated object to track subscriptions. - boost::unordered_map > > mMap; + typedef boost::unordered_map > > MapType; + MapType mMap; bool const mPublic; bool const mProxy; @@ -154,8 +155,15 @@ public: if (ptr->onPingTimer (data)) { - WriteLog (lsWARNING, WSServerHandlerLog) << "Connection pings out"; - cpClient->close (websocketpp::close::status::PROTOCOL_ERROR, "ping timeout"); + cpClient->terminate (false); + try + { + WriteLog (lsDEBUG, WSServerHandlerLog) << + "Ws:: ping_out(" << cpClient->get_socket ().remote_endpoint ().to_string () << ")"; + } + catch (...) + { + } } else cpClient->ping (data); @@ -183,11 +191,13 @@ public: try { - mMap [cpClient] = boost::make_shared < - WSConnectionType - > (boost::ref(m_resourceManager), - boost::ref (m_source), - boost::ref(*this), boost::cref(cpClient)); + std::pair const result ( + mMap.emplace (cpClient, + boost::make_shared < WSConnectionType > (boost::ref(m_resourceManager), + boost::ref (m_source), boost::ref(*this), boost::cref(cpClient)))); + check_postcondition (result.second); + WriteLog (lsDEBUG, WSServerHandlerLog) << + "Ws:: on_open(" << cpClient->get_socket ().remote_endpoint ().to_string () << ")"; } catch (...) { @@ -206,10 +216,28 @@ public: ptr = it->second; } + try + { + WriteLog (lsDEBUG, WSServerHandlerLog) << + "Ws:: on_pong(" << cpClient->get_socket ().remote_endpoint ().to_string () << ")"; + } + catch (...) + { + } ptr->onPong (data); } void on_close (connection_ptr cpClient) + { + doClose (cpClient, "on_close"); + } + + void on_fail (connection_ptr cpClient) + { + doClose (cpClient, "on_fail"); + } + + void doClose (connection_ptr const& cpClient, char const* reason) { // we cannot destroy the connection while holding the map lock or we deadlock with pubLedger wsc_ptr ptr; @@ -218,12 +246,32 @@ public: typename boost::unordered_map::iterator it = mMap.find (cpClient); if (it == mMap.end ()) + { + try + { + WriteLog (lsDEBUG, WSServerHandlerLog) << + "Ws:: " << reason << "(" << + cpClient->get_socket ().remote_endpoint ().to_string () << ") not found"; + } + catch (...) + { + } return; + } ptr = it->second; // prevent the WSConnection from being destroyed until we release the lock mMap.erase (it); } ptr->preDestroy (); // Must be done before we return + try + { + WriteLog (lsDEBUG, WSServerHandlerLog) << + "Ws:: " << reason << "(" << + cpClient->get_socket ().remote_endpoint ().to_string () << ") found"; + } + catch (...) + { + } // Must be done without holding the websocket send lock getApp().getJobQueue ().addJob (jtCLIENT, "WSClient::destroy", @@ -335,7 +383,7 @@ public: { std::string cmd = jvRequest["command"].asString (); job.rename (std::string ("WSClient::") + cmd); - } + } send (cpClient, conn->invokeCommand (jvRequest), false); }