diff --git a/openvidu-browser/src/OpenVidu/Session.ts b/openvidu-browser/src/OpenVidu/Session.ts index 046dddaa..41b788ce 100644 --- a/openvidu-browser/src/OpenVidu/Session.ts +++ b/openvidu-browser/src/OpenVidu/Session.ts @@ -565,7 +565,7 @@ export class Session implements EventDispatcher { * @hidden */ onParticipantLeft(msg): void { - this.getRemoteConnection(msg.name, 'Remote connection ' + msg.name + " unknown when 'onParticipantLeft'. " + + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantLeft'. " + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) .then(connection => { @@ -630,7 +630,7 @@ export class Session implements EventDispatcher { * @hidden */ onParticipantUnpublished(msg): void { - this.getRemoteConnection(msg.name, "Remote connection '" + msg.name + "' unknown when 'onParticipantUnpublished'. " + + this.getRemoteConnection(msg.connectionId, "Remote connection '" + msg.connectionId + "' unknown when 'onParticipantUnpublished'. " + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) .then(connection => { @@ -653,26 +653,33 @@ export class Session implements EventDispatcher { * @hidden */ onParticipantEvicted(msg): void { - /*this.getRemoteConnection(msg.name, 'Remote connection ' + msg.name + " unknown when 'onParticipantLeft'. " + - 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) + if (msg.connectionId === this.connection.connectionId) { + // You have been evicted from the session + if (!!this.sessionId && !this.connection.disposed) { + this.leave(true, msg.reason); + } + } else { + // Other user has been evicted from the session + this.getRemoteConnection(msg.connectionId, 'Remote connection ' + msg.connectionId + " unknown when 'onParticipantEvicted'. " + + 'Existing remote connections: ' + JSON.stringify(Object.keys(this.remoteConnections))) - .then(connection => { - if (!!connection.stream) { - const stream = connection.stream; + .then(connection => { + if (!!connection.stream) { + const stream = connection.stream; - const streamEvent = new StreamEvent(true, this, 'streamDestroyed', stream, 'forceDisconnect'); - this.ee.emitEvent('streamDestroyed', [streamEvent]); - streamEvent.callDefaultBehavior(); + const streamEvent = new StreamEvent(true, this, 'streamDestroyed', stream, msg.reason); + this.ee.emitEvent('streamDestroyed', [streamEvent]); + streamEvent.callDefaultBehavior(); - delete this.remoteStreamsCreated[stream.streamId]; - } - connection.dispose(); - delete this.remoteConnections[connection.connectionId]; - this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent(false, this, 'connectionDestroyed', connection, 'forceDisconnect')]); - }) - .catch(openViduError => { - console.error(openViduError); - });*/ + delete this.remoteStreamsCreated[stream.streamId]; + } + delete this.remoteConnections[connection.connectionId]; + this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent(false, this, 'connectionDestroyed', connection, msg.reason)]); + }) + .catch(openViduError => { + console.error(openViduError); + }); + } } /** @@ -764,7 +771,7 @@ export class Session implements EventDispatcher { */ onSessionClosed(msg): void { console.info('Session closed: ' + JSON.stringify(msg)); - const s = msg.room; + const s = msg.sessionId; if (s !== undefined) { this.ee.emitEvent('session-closed', [{ session: s diff --git a/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java b/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java index 7a218a48..fffed01d 100644 --- a/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java +++ b/openvidu-client/src/main/java/io/openvidu/client/internal/ProtocolElements.java @@ -95,10 +95,12 @@ public class ProtocolElements { public static final String PARTICIPANTJOINED_METADATA_PARAM = "metadata"; public static final String PARTICIPANTLEFT_METHOD = "participantLeft"; - public static final String PARTICIPANTLEFT_NAME_PARAM = "name"; + public static final String PARTICIPANTLEFT_NAME_PARAM = "connectionId"; public static final String PARTICIPANTLEFT_REASON_PARAM = "reason"; public static final String PARTICIPANTEVICTED_METHOD = "participantEvicted"; + public static final String PARTICIPANTEVICTED_CONNECTIONID_PARAM = "connectionId"; + public static final String PARTICIPANTEVICTED_REASON_PARAM = "reason"; public static final String PARTICIPANTPUBLISHED_METHOD = "participantPublished"; public static final String PARTICIPANTPUBLISHED_USER_PARAM = "id"; @@ -113,7 +115,7 @@ public class ProtocolElements { public static final String PARTICIPANTPUBLISHED_VIDEODIMENSIONS_PARAM = "videoDimensions"; public static final String PARTICIPANTUNPUBLISHED_METHOD = "participantUnpublished"; - public static final String PARTICIPANTUNPUBLISHED_NAME_PARAM = "name"; + public static final String PARTICIPANTUNPUBLISHED_NAME_PARAM = "connectionId"; public static final String PARTICIPANTUNPUBLISHED_REASON_PARAM = "reason"; public static final String PARTICIPANTSENDMESSAGE_METHOD = "sendMessage"; @@ -122,7 +124,7 @@ public class ProtocolElements { public static final String PARTICIPANTSENDMESSAGE_TYPE_PARAM = "type"; public static final String ROOMCLOSED_METHOD = "roomClosed"; - public static final String ROOMCLOSED_ROOM_PARAM = "room"; + public static final String ROOMCLOSED_ROOM_PARAM = "sessionId"; public static final String MEDIAERROR_METHOD = "mediaError"; public static final String MEDIAERROR_ERROR_PARAM = "error"; diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java index c60859f7..29e9d22a 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionEventsHandler.java @@ -349,9 +349,12 @@ public class SessionEventsHandler { rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject()); } - public void onParticipantEvicted(Participant participant) { + public void onParticipantEvicted(Participant participant, String reason) { + JsonObject params = new JsonObject(); + params.addProperty(ProtocolElements.PARTICIPANTEVICTED_CONNECTIONID_PARAM, participant.getParticipantPublicId()); + params.addProperty(ProtocolElements.PARTICIPANTEVICTED_REASON_PARAM, reason); rpcNotificationService.sendNotification(participant.getParticipantPrivateId(), - ProtocolElements.PARTICIPANTEVICTED_METHOD, new JsonObject()); + ProtocolElements.PARTICIPANTEVICTED_METHOD, params); } public void sendRecordingStartedNotification(Session session, Recording recording) { diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java index e5c3ad33..ab36a20a 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/SessionManager.java @@ -75,7 +75,8 @@ public abstract class SessionManager { public abstract void joinRoom(Participant participant, String sessionId, Integer transactionId); - public abstract void leaveRoom(Participant participant, Integer transactionId, String reason); + public abstract void leaveRoom(Participant participant, Integer transactionId, String reason, + boolean closeWebSocket); public abstract void publishVideo(Participant participant, MediaOptions mediaOptions, Integer transactionId); @@ -397,7 +398,7 @@ public abstract class SessionManager { * @throws OpenViduException * in case the session doesn't exist or has been already closed */ - private Set closeSession(String sessionId, String reason) { + public Set closeSession(String sessionId, String reason) { Session session = sessions.get(sessionId); if (session == null) { throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, "Session '" + sessionId + "' not found"); @@ -410,21 +411,13 @@ public abstract class SessionManager { Set pids = participants.stream().map(Participant::getParticipantPrivateId).collect(Collectors.toSet()); for (String pid : pids) { try { - session.leave(pid, reason); + this.evictParticipant(pid, reason); } catch (OpenViduException e) { log.warn("Error evicting participant with id '{}' from session '{}'", pid, sessionId, e); } } - if (session.close(reason)) { - sessionEventsHandler.onSessionClosed(sessionId, reason); - } - sessions.remove(sessionId); - sessionProperties.remove(sessionId); - sessionidParticipantpublicidParticipant.remove(sessionId); - sessionidTokenTokenobj.remove(sessionId); - - log.warn("Session '{}' removed and closed", sessionId); + this.closeSessionAndEmptyCollections(session, reason); if (recordingService.sessionIsBeingRecorded(session.getSessionId())) { recordingService.stopRecording(session); @@ -433,4 +426,17 @@ public abstract class SessionManager { return participants; } + public void closeSessionAndEmptyCollections(Session session, String reason) { + if (session.close(reason)) { + sessionEventsHandler.onSessionClosed(session.getSessionId(), reason); + } + sessions.remove(session.getSessionId()); + + sessionProperties.remove(session.getSessionId()); + sessionidParticipantpublicidParticipant.remove(session.getSessionId()); + sessionidTokenTokenobj.remove(session.getSessionId()); + + log.warn("Session '{}' removed and closed", session.getSessionId()); + } + } diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java index d862f707..8956910d 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSessionManager.java @@ -105,7 +105,7 @@ public class KurentoSessionManager extends SessionManager { } @Override - public synchronized void leaveRoom(Participant participant, Integer transactionId, String reason) { + public synchronized void leaveRoom(Participant participant, Integer transactionId, String reason, boolean closeWebSocket) { log.debug("Request [LEAVE_ROOM] ({})", participant.getParticipantPublicId()); KurentoParticipant kParticipant = (KurentoParticipant) participant; @@ -156,26 +156,13 @@ public class KurentoSessionManager extends SessionManager { log.info("Possible collision when closing the session '{}' (not found)", sessionId); remainingParticipants = Collections.emptySet(); } - sessionEventsHandler.onParticipantLeft(participant, sessionId, remainingParticipants, transactionId, null, reason); if (remainingParticipants.isEmpty()) { - log.info("No more participants in session '{}', removing it and closing it", sessionId); - if (session.close(reason)) { - sessionEventsHandler.onSessionClosed(sessionId, "lastParticipantLeft"); - } - sessions.remove(sessionId); - - sessionProperties.remove(sessionId); - sessionidParticipantpublicidParticipant.remove(sessionId); - sessionidTokenTokenobj.remove(sessionId); - + this.closeSessionAndEmptyCollections(session, reason); showTokens(); - - log.warn("Session '{}' removed and closed", sessionId); - } else if (remainingParticipants.size() == 1 && openviduConfig.isRecordingModuleEnabled() && MediaMode.ROUTED.equals(session.getSessionProperties().mediaMode()) && RecordingMode.ALWAYS.equals(session.getSessionProperties().recordingMode()) @@ -188,8 +175,10 @@ public class KurentoSessionManager extends SessionManager { .getParticipantPrivateId(), "EVICT_RECORDER"); } - // Finally close websocket session - sessionEventsHandler.closeRpcSession(participant.getParticipantPrivateId()); + // Finally close websocket session if required + if (closeWebSocket) { + sessionEventsHandler.closeRpcSession(participant.getParticipantPrivateId()); + } } /** @@ -477,8 +466,9 @@ public class KurentoSessionManager extends SessionManager { @Override public void evictParticipant(String participantPrivateId, String reason) throws OpenViduException { Participant participant = this.getParticipant(participantPrivateId); - this.leaveRoom(participant, null, reason); - sessionEventsHandler.onParticipantEvicted(participant); + this.leaveRoom(participant, null, reason, false); + sessionEventsHandler.onParticipantEvicted(participant, reason); + sessionEventsHandler.closeRpcSession(participantPrivateId); } @Override diff --git a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java index 8b65afbb..caf0c7ff 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rest/SessionRestController.java @@ -166,6 +166,17 @@ public class SessionRestController { return new ResponseEntity<>(json, HttpStatus.OK); } + @RequestMapping(value = "/sessions/{sessionId}", method = RequestMethod.DELETE) + public ResponseEntity closeSession(@PathVariable("sessionId") String sessionId) { + Session session = this.sessionManager.getSession(sessionId); + if (session != null) { + this.sessionManager.closeSession(sessionId, "sessionClosedByServer"); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + @SuppressWarnings("unchecked") @RequestMapping(value = "/tokens", method = RequestMethod.POST) public ResponseEntity newToken(@RequestBody Map params) { diff --git a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java index 59a5bd8f..22032a99 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java +++ b/openvidu-server/src/main/java/io/openvidu/server/rpc/RpcHandler.java @@ -203,7 +203,7 @@ public class RpcHandler extends DefaultJsonRpcHandler { Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); if (participant != null) { log.info("Participant {} is leaving session {}", participant.getParticipantPublicId(), sessionId); - sessionManager.leaveRoom(participant, request.getId(), "disconnect"); + sessionManager.leaveRoom(participant, request.getId(), "disconnect", true); log.info("Participant {} has left session {}", participant.getParticipantPublicId(), sessionId); } else { log.warn("Participant with private id {} not found in session {}. " diff --git a/openvidu-test-e2e/docker/chrome/script.sh b/openvidu-test-e2e/docker/chrome/script.sh index 11f51b1e..01476ea9 100755 --- a/openvidu-test-e2e/docker/chrome/script.sh +++ b/openvidu-test-e2e/docker/chrome/script.sh @@ -10,12 +10,8 @@ sudo apt-get -y update && sudo apt-get -y install iptables && sudo apt-get -y in # UDP rules (DROP all) -sudo iptables -A OUTPUT -p udp --dport 0:65535 -j DROP -sudo iptables -A INPUT -p udp --dport 0:65535 -j DROP - sudo iptables -A OUTPUT -o eth0 -p tcp --dport 80 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --dport 443 -j ACCEPT -sudo iptables -A OUTPUT -o eth0 -p tcp --dport 53 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --dport 4444 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --dport 6080 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --dport 5900 -j ACCEPT @@ -25,7 +21,6 @@ sudo iptables -A OUTPUT -o eth0 -p tcp --dport 3478 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 80 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 443 -j ACCEPT -sudo iptables -A OUTPUT -o eth0 -p tcp --sport 53 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 4444 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 6080 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 5900 -j ACCEPT @@ -33,8 +28,20 @@ sudo iptables -A OUTPUT -o eth0 -p tcp --sport 4200 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 4443 -j ACCEPT sudo iptables -A OUTPUT -o eth0 -p tcp --sport 3478 -j ACCEPT +sudo iptables -A OUTPUT -p tcp --sport 53 -j ACCEPT +sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT +sudo iptables -A OUTPUT -p udp --sport 53 -j ACCEPT +sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT +sudo iptables -A INPUT -p tcp --sport 53 -j ACCEPT +sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT +sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT +sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT + sudo iptables -A OUTPUT -o eth0 -p tcp -j DROP +sudo iptables -A OUTPUT -p udp --dport 0:65535 -j DROP +sudo iptables -A INPUT -p udp --dport 0:65535 -j DROP + exit EOF diff --git a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts index 9df9c7a6..2f814df3 100644 --- a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts +++ b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts @@ -356,10 +356,8 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { if (this.sessionEvents.sessionDisconnected) { this.session.on('sessionDisconnected', (event: SessionDisconnectedEvent) => { this.updateEventList('sessionDisconnected', 'No data'); - if (event.reason === 'networkDisconnect') { - this.session = null; - this.OV = null; - } + this.session = null; + this.OV = null; }); } }