diff --git a/server/lib/Lobby.js b/server/lib/Lobby.js index e21be1d..1d7a7d3 100644 --- a/server/lib/Lobby.js +++ b/server/lib/Lobby.js @@ -32,6 +32,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()'); @@ -77,6 +85,8 @@ class Lobby extends EventEmitter { logger.info('parkPeer()'); + if ( this._closed ) return; + const peer = { peerId, socket, consume }; socket.emit('notification', { method: 'enteredLobby', data: {} }); @@ -88,7 +98,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) => { @@ -100,19 +111,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 6335b56..7b0cf00 100644 --- a/server/lib/Room.js +++ b/server/lib/Room.js @@ -98,6 +98,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 = []; @@ -154,6 +164,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()'); @@ -186,6 +215,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); @@ -295,7 +331,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) @@ -319,23 +355,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 8d6ccdb..0b1409d 100755 --- a/server/server.js +++ b/server/server.js @@ -136,6 +136,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)