mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Websocket improvements:
* Log on_close/on_fail/on_open calls. * Ping out connections. * Improve ping logic. * On websocket ping out, close abnormally. * Avoid deadlock when shutting down websocket endpoint
This commit is contained in:
@@ -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 ();
|
||||
|
||||
@@ -74,7 +74,7 @@ private:
|
||||
{
|
||||
ScopedLockType lock (m_endpointLock, __FILE__, __LINE__);
|
||||
|
||||
m_endpoint = new websocketpp::server_multitls (handler);
|
||||
m_endpoint = boost::make_shared<websocketpp::server_multitls> (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<websocketpp::server_multitls> 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 <websocketpp::server_multitls> m_endpoint;
|
||||
boost::shared_ptr<websocketpp::server_multitls> m_endpoint;
|
||||
bool mPublic;
|
||||
bool mProxy;
|
||||
std::string mIp;
|
||||
|
||||
@@ -69,8 +69,9 @@ private:
|
||||
|
||||
protected:
|
||||
// For each connection maintain an associated object to track subscriptions.
|
||||
boost::unordered_map <connection_ptr,
|
||||
boost::shared_ptr <WSConnectionType <endpoint_type> > > mMap;
|
||||
typedef boost::unordered_map <connection_ptr,
|
||||
boost::shared_ptr <WSConnectionType <endpoint_type> > > 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 <endpoint_type>
|
||||
> (boost::ref(m_resourceManager),
|
||||
boost::ref (m_source),
|
||||
boost::ref(*this), boost::cref(cpClient));
|
||||
std::pair <typename MapType::iterator, bool> const result (
|
||||
mMap.emplace (cpClient,
|
||||
boost::make_shared < WSConnectionType <endpoint_type> > (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<connection_ptr, wsc_ptr>::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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user