diff --git a/server/lib/Lobby.js b/server/lib/Lobby.js index 62da0e5..fe88377 100644 --- a/server/lib/Lobby.js +++ b/server/lib/Lobby.js @@ -34,6 +34,14 @@ class Lobby extends EventEmitter this._peers = {}; } + checkEmpty() + { + logger.info('checkEmpty()'); + if (Object.keys(this._peers).length == 0) + return true + else return false; + } + peerList() { logger.info('peerList()'); @@ -75,6 +83,8 @@ class Lobby extends EventEmitter { logger.info('parkPeer()'); + if ( this._closed ) return; + const peer = { peerId, socket, consume }; socket.emit('notification', { method: 'enteredLobby', data: {} }); @@ -86,7 +96,8 @@ class Lobby extends EventEmitter logger.debug( 'Peer "request" event [method:%s, peerId:%s]', request.method, peer.peerId); - + + if (this._closed) return; this._handleSocketRequest(peer, request, cb) .catch((error) => { @@ -98,19 +109,22 @@ class Lobby extends EventEmitter socket.on('disconnect', () => { - if (this._closed) - return; - logger.debug('Peer "close" event [peerId:%s]', peer.peerId); + if (this._closed) return; + this.emit('peerClosed', peer); delete this._peers[peer.peerId]; + + if ( this.checkEmpty() ) this.emit('lobbyEmpty'); }); } async _handleSocketRequest(peer, request, cb) { + logger.debug('_handleSocketRequest [peer:%o], [request:%o]', peer, request); + if (this._closed) return; switch (request.method) { case 'changeDisplayName': diff --git a/server/lib/Room.js b/server/lib/Room.js index e702367..59c64df 100644 --- a/server/lib/Room.js +++ b/server/lib/Room.js @@ -99,6 +99,16 @@ class Room extends EventEmitter }); }); + // If nobody left in lobby we should check if room is empty too and initiating + // rooms selfdestruction sequence + this._lobby.on('lobbyEmpty', () => + { + if ( this.checkEmpty() ) + { + this.selfDestructCountdown(); + } + }) + this._chatHistory = []; this._fileHistory = []; @@ -155,6 +165,25 @@ class Room extends EventEmitter return this._roomId; } + selfDestructCountdown() + { + logger.debug('selfDestructCountdown() started') + setTimeout(() => + { + if (this._closed) + return; + + if (this.checkEmpty() && this._lobby.checkEmpty()) + { + logger.info( + 'Room deserted for some time, closing the room [roomId:%s]', + this._roomId); + this.close(); + } + else logger.debug('selfDestructCountdown() aborted; room is not empty!') + }, 10000); + } + close() { logger.debug('close()'); @@ -187,6 +216,13 @@ class Room extends EventEmitter ); } + // checks both room and lobby + checkEmpty() + { + if (( Object.keys(this._peers).length == 0) && (this._lobby.checkEmpty())) return true + else return false; + } + handleConnection({ peerId, consume, socket }) { logger.info('handleConnection() [peerId:"%s"]', peerId); @@ -296,7 +332,7 @@ class Room extends EventEmitter if (this._closed) return; - logger.debug('Peer "close" event [peerId:%s]', peer.id); + logger.debug('Peer "disconnect" event [peerId:%s]', peer.id); // If the Peer was joined, notify all Peers. if (peer.data.joined) @@ -320,23 +356,10 @@ class Room extends EventEmitter delete this._peers[peer.id]; - // If this is the latest Peer in the room, close the room after a while. - if (Object.keys(this._peers).length == 0) + // If this is the latest Peer in the room and lobby is empty, close the room after a while. + if (this.checkEmpty()) { - setTimeout(() => - { - if (this._closed) - return; - - if (Object.keys(this._peers).length == 0) - { - logger.info( - 'last Peer in the room left, closing the room [roomId:%s]', - this._roomId); - - this.close(); - } - }, 10000); + this.selfDestructCountdown(); } }); } diff --git a/server/server.js b/server/server.js index 4e42518..c1c85d9 100755 --- a/server/server.js +++ b/server/server.js @@ -126,6 +126,15 @@ async function run() room.logStatus(); } }, 120000); + + // check for deserted rooms + setInterval(() => + { + for (const room of rooms.values()) + { + room.checkEmpty(); + } + }, 10000); } async function setupAuth(oidcIssuer)