From a4033a44c33f84c38a397386e8d60e80d1847a79 Mon Sep 17 00:00:00 2001 From: ehouse Date: Sat, 3 Sep 2005 15:41:17 +0000 Subject: [PATCH] when one device is disconnected for heartbeat, tell others it's going away. --- xwords4/relay/cref.cpp | 39 +++++++++++++++++++++++++++++++++------ xwords4/relay/cref.h | 1 + xwords4/relay/xwrelay.h | 13 +++++++++---- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/xwords4/relay/cref.cpp b/xwords4/relay/cref.cpp index f820beced..d2347331c 100644 --- a/xwords4/relay/cref.cpp +++ b/xwords4/relay/cref.cpp @@ -152,10 +152,10 @@ void CookieRef::notifyDisconn( const CRefEvent* evt ) { int socket = evt->u.disnote.socket; - unsigned char buf[2]; - - buf[0] = XWRELAY_DISCONNECT; - buf[1] = evt->u.disnote.why; + unsigned char buf[] = { + XWRELAY_DISCONNECT_YOU, + evt->u.disnote.why + }; send_with_length( socket, buf, sizeof(buf) ); } /* notifyDisconn */ @@ -225,7 +225,7 @@ CookieRef::_CheckHeartbeats( time_t now ) map::iterator iter = m_hostSockets.begin(); while ( iter != m_hostSockets.end() ) { time_t last = iter->second.m_lastHeartbeat; - if ( (now - last) > GetHeartbeat() * 2 ) { + if ( (now - last) > GetHeartbeat() ) { pushHeartFailedEvent( iter->second.m_socket ); } ++iter; @@ -403,7 +403,9 @@ CookieRef::handleEvents() disconnectSockets( 0, XWRELAY_ERROR_TIMEOUT ); break; case XW_ACTION_HEARTDISCONNECT: - disconnectSockets( evt.u.heart.socket, XWRELAY_ERROR_HEART ); + notifyOthers( evt.u.heart.socket, XWRELAY_ERROR_HEART_OTHER ); + disconnectSockets( evt.u.heart.socket, + XWRELAY_ERROR_HEART_YOU ); break; case XW_ACTION_NOTEHEART: @@ -548,6 +550,31 @@ CookieRef::checkFromServer( const CRefEvent* evt ) } } +void +CookieRef::notifyOthers( int socket, XWREASON why ) +{ + assert( socket != 0 ); + + RWReadLock ml( &m_sockets_rwlock ); + + map::iterator iter = m_hostSockets.begin(); + while ( iter != m_hostSockets.end() ) { + int other = iter->second.m_socket; + if ( other != socket ) { + unsigned char buf[4]; + buf[0] = XWRELAY_DISCONNECT_OTHER; + buf[1] = why; + + HostID id = iter->first; + short tmp = htons( id ); + memcpy( &buf[2], &tmp, 2 ); + + send_with_length( other, buf, sizeof(buf) ); + } + ++iter; + } +} /* notifyOthers */ + void CookieRef::disconnectSockets( int socket, XWREASON why ) { diff --git a/xwords4/relay/cref.h b/xwords4/relay/cref.h index 8a95dc352..ea7afcbc9 100644 --- a/xwords4/relay/cref.h +++ b/xwords4/relay/cref.h @@ -157,6 +157,7 @@ class CookieRef { void forward( const CRefEvent* evt ); void checkDest( const CRefEvent* evt ); void checkFromServer( const CRefEvent* evt ); + void notifyOthers( int socket, XWREASON why ); void disconnectSockets( int socket, XWREASON why ); void noteHeartbeat(const CRefEvent* evt); diff --git a/xwords4/relay/xwrelay.h b/xwords4/relay/xwrelay.h index b8e22debf..fee9cd4c8 100644 --- a/xwords4/relay/xwrelay.h +++ b/xwords4/relay/xwrelay.h @@ -43,9 +43,13 @@ enum { XWRELAY_NONE /* 0 is an illegal value */ XWRELAY_RECONNECT. Format: heartbeat_seconds: 2; connectionID: 2; */ - , XWRELAY_DISCONNECT - /* Sent from relay when existing connection is terminated. Includes - reason code */ + , XWRELAY_DISCONNECT_YOU + /* Sent from relay when existing connection is terminated. + Format: errorCode: 1 */ + + , XWRELAY_DISCONNECT_OTHER + /* Another device has left the game. + Format: errorCode: 1; lostHostId: 2 */ , XWRELAY_CONNECTDENIED /* The relay says go away. Format: reason code: 1 */ @@ -81,7 +85,8 @@ typedef enum { ,XWRELAY_ERROR_RELAYBUSY ,XWRELAY_ERROR_SHUTDOWN /* relay's going down */ ,XWRELAY_ERROR_TIMEOUT /* Other players didn't show */ - ,XWRELAY_ERROR_HEART /* Haven't heard from you in too long */ + ,XWRELAY_ERROR_HEART_YOU /* Haven't heard from somebody in too long */ + ,XWRELAY_ERROR_HEART_OTHER ,XWRELAY_ERROR_LASTERR } XWREASON;