-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix connection status issue (#2519) #3364
base: main
Are you sure you want to change the base?
Changes from all commits
38fb414
a5af8cc
535f781
21815c1
d7b4b8b
66edab5
49402c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ CChannel::CChannel ( const bool bNIsServer ) : | |
bIsEnabled ( false ), | ||
bIsServer ( bNIsServer ), | ||
bIsIdentified ( false ), | ||
bDisconnectAndDisable ( false ), | ||
iAudioFrameSizeSamples ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ), | ||
SignalLevelMeter ( false, 0.5 ) // server mode with mono out and faster smoothing | ||
{ | ||
|
@@ -125,7 +126,8 @@ void CChannel::SetEnable ( const bool bNEnStat ) | |
QMutexLocker locker ( &Mutex ); | ||
|
||
// set internal parameter | ||
bIsEnabled = bNEnStat; | ||
bIsEnabled = bNEnStat; | ||
bDisconnectAndDisable = false; | ||
|
||
// The support for the packet sequence number must be reset if the client | ||
// disconnects from a server since we do not yet know if the next server we | ||
|
@@ -511,6 +513,24 @@ void CChannel::Disconnect() | |
// (assuming that no audio packet is received in the meantime) | ||
iConTimeOut = 1; // a small number > 0 | ||
} | ||
|
||
if ( !bIsServer ) | ||
{ | ||
if ( IsConnected() ) | ||
{ | ||
// for a Client, block further audio data and disable the channel as soon as Disconnect() is called | ||
// TODO: Add reasoning from #2550 | ||
bDisconnectAndDisable = true; | ||
} | ||
else | ||
{ | ||
// For disconnected clients set defaults | ||
|
||
bDisconnectAndDisable = false; | ||
bIsEnabled = false; | ||
iConTimeOut = 0; | ||
} | ||
} | ||
} | ||
|
||
void CChannel::PutProtocolData ( const int iRecCounter, const int iRecID, const CVector<uint8_t>& vecbyMesBodyData, const CHostAddress& RecHostAddr ) | ||
|
@@ -532,9 +552,9 @@ EPutDataStat CChannel::PutAudioData ( const CVector<uint8_t>& vecbyData, const i | |
EPutDataStat eRet = PS_GEN_ERROR; | ||
|
||
// Only process audio data if: | ||
// - for client only: the packet comes from the server we want to talk to | ||
// - for client only: the packet comes from the server we want to talk to and we aren't disconnecting | ||
// - the channel is enabled | ||
if ( ( bIsServer || ( GetAddress() == RecHostAddr ) ) && IsEnabled() ) | ||
if ( ( bIsServer || ( !bIsServer && GetAddress() == RecHostAddr && !bDisconnectAndDisable ) ) && IsEnabled() ) | ||
{ | ||
MutexSocketBuf.lock(); | ||
{ | ||
|
@@ -622,6 +642,11 @@ EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData, const int iNumByte | |
eGetStatus = GS_CHAN_NOW_DISCONNECTED; | ||
iConTimeOut = 0; // make sure we do not have negative values | ||
|
||
if ( bDisconnectAndDisable && !bIsServer ) | ||
{ | ||
bDisconnectAndDisable = false; | ||
bIsEnabled = false; | ||
} | ||
// reset network transport properties | ||
ResetNetworkTransportProperties(); | ||
} | ||
|
@@ -643,6 +668,13 @@ EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData, const int iNumByte | |
{ | ||
// channel is disconnected | ||
eGetStatus = GS_CHAN_NOT_CONNECTED; | ||
|
||
if ( bDisconnectAndDisable && !bIsServer ) | ||
{ | ||
bDisconnectAndDisable = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ??! So these get set to the same values whether |
||
bIsEnabled = false; | ||
iConTimeOut = 0; | ||
} | ||
} | ||
} | ||
MutexSocketBuf.unlock(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,6 @@ | |
/* Implementation *************************************************************/ | ||
CClient::CClient ( const quint16 iPortNumber, | ||
const quint16 iQosNumber, | ||
const QString& strConnOnStartupAddress, | ||
const QString& strMIDISetup, | ||
const bool bNoAutoJackConnect, | ||
const QString& strNClientName, | ||
|
@@ -184,13 +183,6 @@ CClient::CClient ( const quint16 iPortNumber, | |
// start the socket (it is important to start the socket after all | ||
// initializations and connections) | ||
Socket.Start(); | ||
|
||
// do an immediate start if a server address is given | ||
if ( !strConnOnStartupAddress.isEmpty() ) | ||
{ | ||
SetServerAddr ( strConnOnStartupAddress ); | ||
Start(); | ||
} | ||
ann0see marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
CClient::~CClient() | ||
|
@@ -337,7 +329,7 @@ void CClient::CreateServerJitterBufferMessage() | |
void CClient::OnCLPingReceived ( CHostAddress InetAddr, int iMs ) | ||
{ | ||
// make sure we are running and the server address is correct | ||
if ( IsRunning() && ( InetAddr == Channel.GetAddress() ) ) | ||
if ( Channel.IsEnabled() && ( InetAddr == Channel.GetAddress() ) ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't about the channel being enabled. It's about whether the client is running. It's a different intent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the initial PR confused active channel and active client: #2550 (comment) This difference needs documentation. IMO: Add (like for JSON-RPC) respective technical documentation before the respective methods. As end goal: Write them for every function, for now: Write docs while changing. |
||
{ | ||
// take care of wrap arounds (if wrapping, do not use result) | ||
const int iCurDiff = EvaluatePingMessage ( iMs ); | ||
|
@@ -773,11 +765,8 @@ void CClient::OnHandledSignal ( int sigNum ) | |
{ | ||
case SIGINT: | ||
case SIGTERM: | ||
// if connected, terminate connection (needed for headless mode) | ||
if ( IsRunning() ) | ||
{ | ||
Stop(); | ||
} | ||
// if connected, terminate connection | ||
Disconnect(); | ||
|
||
// this should trigger OnAboutToQuit | ||
QCoreApplication::instance()->exit(); | ||
|
@@ -876,18 +865,13 @@ void CClient::Start() | |
|
||
void CClient::Stop() | ||
{ | ||
// stop audio interface | ||
Sound.Stop(); | ||
|
||
// disable channel | ||
Channel.SetEnable ( false ); | ||
// start disconnection | ||
// Channel.Disconnect() should automatically disable Channel as soon as disconnected. | ||
// Note that this only works if sound is active! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So why make the changes here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe it's mainly moving around the Channel.Disconnect() and Sound.Stop() code around. This may be the actual bug fix? |
||
Channel.Disconnect(); | ||
|
||
// wait for approx. 100 ms to make sure no audio packet is still in the | ||
// network queue causing the channel to be reconnected right after having | ||
// received the disconnect message (seems not to gain much, disconnect is | ||
// still not working reliably) | ||
QTime DieTime = QTime::currentTime().addMSecs ( 100 ); | ||
while ( QTime::currentTime() < DieTime ) | ||
QTime DieTime = QTime::currentTime().addMSecs ( 500 ); | ||
while ( ( QTime::currentTime() < DieTime ) && Channel.IsEnabled() ) | ||
{ | ||
// exclude user input events because if we use AllEvents, it happens | ||
// that if the user initiates a connection and disconnection quickly | ||
|
@@ -896,6 +880,19 @@ void CClient::Stop() | |
QCoreApplication::processEvents ( QEventLoop::ExcludeUserInputEvents, 100 ); | ||
} | ||
|
||
// Now stop the audio interface | ||
Sound.Stop(); | ||
|
||
// in case we timed out, log warning and make sure Channel is disabled | ||
if ( Channel.IsEnabled() ) | ||
{ | ||
//### TODO: BEGIN ###// | ||
// Add error logging | ||
//### TODO: END ###// | ||
|
||
Channel.SetEnable ( false ); | ||
} | ||
|
||
// Send disconnect message to server (Since we disable our protocol | ||
// receive mechanism with the next command, we do not evaluate any | ||
// respond from the server, therefore we just hope that the message | ||
|
@@ -908,6 +905,46 @@ void CClient::Stop() | |
SignalLevelMeter.Reset(); | ||
} | ||
|
||
bool CClient::Connect ( QString strServerAddress, QString strServerName ) | ||
ann0see marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
if ( !Channel.IsEnabled() ) | ||
{ | ||
// Set server address and connect if valid address was supplied | ||
if ( SetServerAddr ( strServerAddress ) ) | ||
{ | ||
|
||
Start(); | ||
|
||
emit Connecting ( strServerName ); | ||
|
||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool CClient::Disconnect() | ||
{ | ||
if ( Channel.IsEnabled() ) | ||
{ | ||
Stop(); | ||
|
||
emit Disconnected(); | ||
|
||
return true; | ||
} | ||
else | ||
{ | ||
// make sure sound is stopped too | ||
Sound.Stop(); | ||
|
||
emit Disconnected(); | ||
|
||
return false; | ||
} | ||
} | ||
|
||
void CClient::Init() | ||
{ | ||
// check if possible frame size factors are supported | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,7 +110,6 @@ class CClient : public QObject | |
public: | ||
CClient ( const quint16 iPortNumber, | ||
const quint16 iQosNumber, | ||
const QString& strConnOnStartupAddress, | ||
const QString& strMIDISetup, | ||
const bool bNoAutoJackConnect, | ||
const QString& strNClientName, | ||
|
@@ -121,8 +120,11 @@ class CClient : public QObject | |
|
||
void Start(); | ||
void Stop(); | ||
bool Connect ( QString strServerAddress, QString strServerName ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does make sense to introduce an easy to call Connect() and Disconnect() method IMO, so this is good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having these in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree. That's issue #3367 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Factored out into #3372 |
||
bool Disconnect(); | ||
|
||
bool IsRunning() { return Sound.IsRunning(); } | ||
bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } | ||
bool IsCallbackEntered() const { return Sound.IsCallbackEntered(); } // For OnTimerCheckAudioDeviceOk only | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reverted naming. May need some in depth review and discussion. |
||
bool SetServerAddr ( QString strNAddr ); | ||
|
||
double GetLevelForMeterdBLeft() { return SignalLevelMeter.GetLevelForMeterdBLeftOrMono(); } | ||
|
@@ -427,6 +429,7 @@ protected slots: | |
|
||
void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector<uint16_t> vecLevelList ); | ||
|
||
void Connecting ( QString strServerName ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably a missing slot. |
||
void Disconnected(); | ||
void SoundDeviceChanged ( QString strError ); | ||
void ControllerInFaderLevel ( int iChannelIdx, int iValue ); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this done when the disconnect actually happens, rather than here? Like in line 645? Is this just duplicated? Or is there a reason for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a reason for it.
It's probably trying to ensure that bDisconnectAndDisable is representing the client being in process of disconnecting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see what job it's doing that setting
iConTimeOut
to 1 doesn't already do. It still needsiConTimeOut
set to 1, too, so it just adds complexity rather than removing it, without improving readability either.