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:
@@ -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 )
|
||||
{
|
||||
|
@@ -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:
|
||||
|
@@ -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 );
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -22,6 +22,7 @@
|
||||
|
||||
WebSocketThreadController::WebSocketThreadController( QObject* sip )
|
||||
: QThread( nullptr )
|
||||
, m_webSocket( nullptr )
|
||||
, m_sip( sip )
|
||||
{
|
||||
}
|
||||
|
Reference in New Issue
Block a user