1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-09-08 21:20:45 +02:00

Improve connection handling and close behavior

This commit is contained in:
Jeff Mitchell
2013-05-21 12:16:07 -04:00
parent a298f60b74
commit e1ea2feefd
5 changed files with 75 additions and 63 deletions

View File

@@ -69,8 +69,7 @@ HatchetSipPlugin::~HatchetSipPlugin()
m_webSocketThreadController->quit();
m_webSocketThreadController->wait( 60000 );
delete m_webSocketThreadController;
m_webSocketThreadController = 0;
delete m_webSocketThreadController.data();
}
m_sipState = Closed;
@@ -120,6 +119,13 @@ HatchetSipPlugin::connectPlugin()
m_webSocketThreadController = QPointer< WebSocketThreadController >( new WebSocketThreadController( this ) );
if ( !m_webSocketThreadController )
{
tLog() << Q_FUNC_INFO << "Could not create a new thread, bailing";
disconnectPlugin();
return;
}
hatchetAccount()->setConnectionState( Tomahawk::Accounts::Account::Connecting );
hatchetAccount()->fetchAccessTokens();
}
@@ -128,19 +134,10 @@ HatchetSipPlugin::connectPlugin()
void
HatchetSipPlugin::disconnectPlugin()
{
if ( m_webSocketThreadController )
{
m_webSocketThreadController->quit();
m_webSocketThreadController->wait( 60000 );
delete m_webSocketThreadController;
m_webSocketThreadController = 0;
}
m_sipState = Closed;
m_version = 0;
hatchetAccount()->setConnectionState( Tomahawk::Accounts::Account::Disconnected );
if ( m_webSocketThreadController && m_webSocketThreadController->isRunning() )
emit disconnectWebSocket();
else
webSocketDisconnected();
}
@@ -189,10 +186,6 @@ HatchetSipPlugin::connectWebSocket()
tLog() << Q_FUNC_INFO << "Connecting to Dreamcatcher endpoint at: " << url;
m_webSocketThreadController->setUrl( url );
// connect( m_ws.data(), SIGNAL( opened() ), this, SLOT( onWsOpened() ) );
// connect( m_ws.data(), SIGNAL( failed( QString ) ), this, SLOT( onWsFailed( QString ) ) );
// connect( m_ws.data(), SIGNAL( closed( QString ) ), this, SLOT( onWsClosed( QString ) ) );
// connect( m_ws.data(), SIGNAL( message( QString ) ), this, SLOT( onWsMessage( QString ) ) );
m_webSocketThreadController->start();
}
@@ -229,6 +222,18 @@ void
HatchetSipPlugin::webSocketDisconnected()
{
tLog() << Q_FUNC_INFO << "WebSocket disconnected";
if ( m_webSocketThreadController )
{
m_webSocketThreadController->quit();
m_webSocketThreadController->wait( 60000 );
delete m_webSocketThreadController.data();
}
m_sipState = Closed;
m_version = 0;
hatchetAccount()->setConnectionState( Tomahawk::Accounts::Account::Disconnected );
m_sipState = Closed;
}
@@ -257,22 +262,6 @@ HatchetSipPlugin::sendBytes( const QVariantMap& jsonMap ) const
}
void
HatchetSipPlugin::onWsFailed( const QString &msg )
{
tLog() << Q_FUNC_INFO << "WebSocket failed with message: " << msg;
disconnectPlugin();
}
void
HatchetSipPlugin::onWsClosed( const QString &msg )
{
tLog() << Q_FUNC_INFO << "WebSocket closed with message: " << msg;
disconnectPlugin();
}
void
HatchetSipPlugin::messageReceived( const QByteArray &msg )
{

View File

@@ -71,8 +71,6 @@ private slots:
void dbSyncTriggered();
void messageReceived( const QByteArray& msg );
void connectWebSocket();
void onWsFailed( const QString &msg );
void onWsClosed( const QString &msg );
void oplogFetched( const QString& sinceguid, const QString& lastguid, const QList< dbop_ptr > ops ) const;
private:

View File

@@ -34,6 +34,7 @@ WebSocket::WebSocket( const QString& url )
tLog() << Q_FUNC_INFO << "WebSocket constructing";
m_client = std::unique_ptr< hatchet_client >( new hatchet_client() );
m_client->set_message_handler( std::bind(&onMessage, this, std::placeholders::_1, std::placeholders::_2 ) );
m_client->set_close_handler( std::bind(&onClose, this, std::placeholders::_1 ) );
m_client->register_ostream( &m_outputStream );
}
@@ -44,16 +45,7 @@ WebSocket::~WebSocket()
m_connection.reset();
if ( m_socket )
{
if ( m_socket->state() == QAbstractSocket::ConnectedState )
{
QObject::disconnect( m_socket, SIGNAL( stateChanged( QAbstractSocket::SocketState ) ) );
m_socket->disconnectFromHost();
QObject::connect( m_socket, SIGNAL( disconnected() ), m_socket, SLOT( deleteLater() ) );
}
else
m_socket->deleteLater();
}
delete m_socket.data();
m_client.reset();
}
@@ -66,8 +58,9 @@ WebSocket::setUrl( const QString &url )
if ( m_url == url )
return;
// We'll let automatic reconnection handle things
if ( m_socket && m_socket->isEncrypted() )
reconnectWs();
disconnectWs();
}
@@ -98,24 +91,45 @@ WebSocket::connectWs()
void
WebSocket::disconnectWs()
WebSocket::disconnectWs( websocketpp::close::status::value status, const QString &reason )
{
tLog() << Q_FUNC_INFO << "Disconnecting";
m_outputStream.seekg( std::ios_base::end );
m_outputStream.seekp( std::ios_base::end );
error_code ec;
if ( m_connection )
m_connection.reset();
m_queuedMessagesToSend.empty();
m_socket->disconnectFromHost();
{
m_connection->close( status, reason.toAscii().constData(), ec );
QMetaObject::invokeMethod( this, "readOutput", Qt::QueuedConnection );
QTimer::singleShot( 5000, this, SLOT( disconnectSocket() ) ); //safety
return;
}
disconnectSocket();
}
void
WebSocket::reconnectWs()
WebSocket::disconnectSocket()
{
tLog() << Q_FUNC_INFO << "Reconnecting";
QMetaObject::invokeMethod( this, "disconnectWs", Qt::QueuedConnection );
QMetaObject::invokeMethod( this, "connectWs", Qt::QueuedConnection );
if ( m_socket && m_socket->state() == QAbstractSocket::ConnectedState )
m_socket->disconnectFromHost();
else
QMetaObject::invokeMethod( this, "cleanup", Qt::QueuedConnection );
QTimer::singleShot( 5000, this, SLOT( cleanup() ) ); //safety
}
void
WebSocket::cleanup()
{
tLog() << Q_FUNC_INFO << "Cleaning up";
m_outputStream.seekg( std::ios_base::end );
m_outputStream.seekp( std::ios_base::end );
m_queuedMessagesToSend.empty();
if ( m_connection )
m_connection.reset();
emit disconnected();
}
@@ -132,7 +146,7 @@ WebSocket::socketStateChanged( QAbstractSocket::SocketState state )
tLog() << Q_FUNC_INFO << "Got a double closing state, cleaning up and emitting disconnected";
m_socket->deleteLater();
m_lastSocketState = QAbstractSocket::UnconnectedState;
emit disconnected();
QMetaObject::invokeMethod( this, "cleanup", Qt::QueuedConnection );
return;
}
break;
@@ -142,7 +156,7 @@ WebSocket::socketStateChanged( QAbstractSocket::SocketState state )
tLog() << Q_FUNC_INFO << "Socket now unconnected, cleaning up and emitting disconnected";
m_socket->deleteLater();
m_lastSocketState = QAbstractSocket::UnconnectedState;
emit disconnected();
QMetaObject::invokeMethod( this, "cleanup", Qt::QueuedConnection );
return;
default:
;
@@ -164,7 +178,7 @@ WebSocket::sslErrors( const QList< QSslError >& errors )
void
WebSocket::encrypted()
{
tLog() << Q_FUNC_INFO << "Encrypted connection to Hatchet established";
tLog() << Q_FUNC_INFO << "Encrypted connection to Dreamcatcher established";
error_code ec;
// Adjust wss:// to ws:// in the URL so it doesn't complain that the transport isn't encrypted
QString url = m_url.toString();
@@ -289,3 +303,10 @@ onMessage( WebSocket* ws, websocketpp::connection_hdl, hatchet_client::message_p
std::string payload = msg->get_payload();
ws->decodedMessage( QByteArray( payload.data(), payload.length() ) );
}
void
onClose( WebSocket *ws, websocketpp::connection_hdl )
{
tLog() << Q_FUNC_INFO << "Handling message";
QMetaObject::invokeMethod( ws, "disconnectSocket", Qt::QueuedConnection );
}

View File

@@ -34,6 +34,7 @@ typedef typename websocketpp::client< websocketpp::config::hatchet_client > hatc
class WebSocket;
void onMessage( WebSocket* ws, websocketpp::connection_hdl, hatchet_client::message_ptr msg );
void onClose( WebSocket* ws, websocketpp::connection_hdl );
class DLLEXPORT WebSocket : public QObject
{
@@ -50,14 +51,15 @@ signals:
public slots:
void setUrl( const QString& url );
void connectWs();
void disconnectWs();
void disconnectWs( websocketpp::close::status::value status = websocketpp::close::status::normal, const QString& reason = QString( "Disconnecting" ) );
void encodeMessage( const QByteArray& bytes );
private slots:
void socketStateChanged( QAbstractSocket::SocketState state );
void sslErrors( const QList< QSslError >& errors );
void disconnectSocket();
void cleanup();
void encrypted();
void reconnectWs();
void readOutput();
void socketReadyRead();
@@ -65,6 +67,7 @@ private:
Q_DISABLE_COPY( WebSocket )
friend void onMessage( WebSocket *ws, websocketpp::connection_hdl, hatchet_client::message_ptr msg );
friend void onClose( WebSocket *ws, websocketpp::connection_hdl );
QUrl m_url;
std::stringstream m_outputStream;

View File

@@ -22,6 +22,7 @@
WebSocketThreadController::WebSocketThreadController( QObject* sip )
: QThread( nullptr )
, m_webSocket( nullptr )
, m_sip( sip )
{
}