diff --git a/openvidu-server/docker/utils/coturn-shared-key.template b/openvidu-server/docker/utils/coturn-shared-key.template index bffb7f40..3ffb1f09 100644 --- a/openvidu-server/docker/utils/coturn-shared-key.template +++ b/openvidu-server/docker/utils/coturn-shared-key.template @@ -14,4 +14,4 @@ # at the .env file of OpenVidu Server deployment # # ------------------------------------------------------------------------------ -COTURN_SHARED_SECRET_KEY={{COTURN_SHARED_SECRET_KEY}} \ No newline at end of file +COTURN_SHARED_SECRET_KEY={{COTURN_SHARED_SECRET_KEY}} diff --git a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java index e2e929ac..527279e9 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java +++ b/openvidu-server/src/main/java/io/openvidu/server/config/OpenviduConfig.java @@ -35,6 +35,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; @@ -159,7 +160,12 @@ public class OpenviduConfig { private Integer openviduStreamsVideoMinSendBandwidth; - private String coturnIp; + /** + * Map which relates used Coturn IP per Media Node. + * Depending on which media node will be used for the session, + * a coturn IP should be sent to the browser and Kurento. + */ + private ConcurrentHashMap mapKmsUriCoturnIp = new ConcurrentHashMap<>(); private int coturnPort; @@ -334,8 +340,8 @@ public class OpenviduConfig { return this.openviduStreamsVideoMinSendBandwidth; } - public String getCoturnIp() { - return this.coturnIp; + public String getCoturnIp(String kmsUri) { + return this.mapKmsUriCoturnIp.get(kmsUri); } public int getCoturnPort() { @@ -641,15 +647,21 @@ public class OpenviduConfig { } private void checkCoturnIp() { + if (this.getKmsUris().isEmpty()) { + throw new IllegalArgumentException("'KMS_URIS' should contain at least one KMS url"); + } + String firstKmsWsUri = this.getKmsUris().get(0); String property = "COTURN_IP"; - coturnIp = asOptionalIPv4OrIPv6(property); - - if (coturnIp == null || this.coturnIp.isEmpty()) { + String coturnIp = asOptionalIPv4OrIPv6(property); + if (coturnIp == null || coturnIp.isEmpty()) { try { - this.coturnIp = new URL(this.getFinalUrl()).getHost(); + coturnIp = new URL(this.getFinalUrl()).getHost(); + this.mapKmsUriCoturnIp.put(firstKmsWsUri, coturnIp); } catch (MalformedURLException e) { log.error("Can't get Domain name from OpenVidu public Url: " + e.getMessage()); } + } else { + this.mapKmsUriCoturnIp.put(firstKmsWsUri, coturnIp); } } 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 50d0ac3f..768ea975 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 @@ -74,7 +74,7 @@ public class SessionEventsHandler { CDR.recordSessionDestroyed(session, reason); } - public void onParticipantJoined(Participant participant, String sessionId, Set existingParticipants, + public void onParticipantJoined(Participant participant, String sessionId, String coturnIp, Set existingParticipants, Integer transactionId, OpenViduException error) { if (error != null) { rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error); @@ -184,7 +184,8 @@ public class SessionEventsHandler { result.addProperty(ProtocolElements.PARTICIPANTJOINED_ROLE_PARAM, participant.getToken().getRole().name()); } - result.addProperty(ProtocolElements.PARTICIPANTJOINED_COTURNIP_PARAM, openviduConfig.getCoturnIp()); + + result.addProperty(ProtocolElements.PARTICIPANTJOINED_COTURNIP_PARAM, coturnIp); result.addProperty(ProtocolElements.PARTICIPANTJOINED_COTURNPORT_PARAM, openviduConfig.getCoturnPort()); List customIceServers = participant.getToken().getCustomIceServers(); if (customIceServers != null && !customIceServers.isEmpty()) { 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 499a99dc..ec339ea0 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 @@ -136,7 +136,7 @@ public class KurentoSessionManager extends SessionManager { String error = "Timeout of " + KmsManager.MAX_SECONDS_LOCK_WAIT + " seconds waiting to acquire lock"; log.error(error); - sessionEventsHandler.onParticipantJoined(participant, sessionId, null, transactionId, + sessionEventsHandler.onParticipantJoined(participant, sessionId, null, null, transactionId, new OpenViduException(Code.ROOM_CANNOT_BE_CREATED_ERROR_CODE, error)); return; } @@ -168,7 +168,8 @@ public class KurentoSessionManager extends SessionManager { try { existingParticipants = getParticipants(sessionId); kSession.join(participant); - sessionEventsHandler.onParticipantJoined(participant, sessionId, existingParticipants, + String coturnIp = openviduConfig.getCoturnIp(kSession.getKms().getUri()); + sessionEventsHandler.onParticipantJoined(participant, sessionId, coturnIp, existingParticipants, transactionId, null); } finally { kSession.joinLeaveLock.unlock(); @@ -177,21 +178,21 @@ public class KurentoSessionManager extends SessionManager { log.error( "Timeout waiting for join-leave Session lock to be available for participant {} of session {} in joinRoom", participant.getParticipantPublicId(), sessionId); - sessionEventsHandler.onParticipantJoined(participant, sessionId, null, transactionId, + sessionEventsHandler.onParticipantJoined(participant, sessionId, null, null, transactionId, new OpenViduException(Code.GENERIC_ERROR_CODE, "Timeout waiting for Session lock")); } } catch (InterruptedException e) { log.error( "InterruptedException waiting for join-leave Session lock to be available for participant {} of session {} in joinRoom", participant.getParticipantPublicId(), sessionId); - sessionEventsHandler.onParticipantJoined(participant, sessionId, null, transactionId, + sessionEventsHandler.onParticipantJoined(participant, sessionId, null,null, transactionId, new OpenViduException(Code.GENERIC_ERROR_CODE, "InterruptedException waiting for Session lock")); } } catch (OpenViduException e) { log.error("PARTICIPANT {}: Error joining/creating session {}", participant.getParticipantPublicId(), sessionId, e); - sessionEventsHandler.onParticipantJoined(participant, sessionId, null, transactionId, e); + sessionEventsHandler.onParticipantJoined(participant, sessionId, null,null, transactionId, e); } } diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/endpoint/MediaEndpoint.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/endpoint/MediaEndpoint.java index e2801363..e25b6548 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/endpoint/MediaEndpoint.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/endpoint/MediaEndpoint.java @@ -299,9 +299,10 @@ public abstract class MediaEndpoint { @Override public void onSuccess(WebRtcEndpoint result) throws Exception { webEndpoint = result; - - if (openviduConfig.getCoturnIp() != null && !openviduConfig.getCoturnIp().isEmpty()) { - webEndpoint.setStunServerAddress(openviduConfig.getCoturnIp()); + String kmsUri = owner.getSession().getKms().getUri(); + String coturnIp = openviduConfig.getCoturnIp(kmsUri); + if (coturnIp != null && !coturnIp.isEmpty()) { + webEndpoint.setStunServerAddress(coturnIp); webEndpoint.setStunServerPort(openviduConfig.getCoturnPort()); } diff --git a/openvidu-server/src/test/java/io/openvidu/server/test/integration/WebhookIntegrationTest.java b/openvidu-server/src/test/java/io/openvidu/server/test/integration/WebhookIntegrationTest.java index 7d4db302..2bf029ca 100644 --- a/openvidu-server/src/test/java/io/openvidu/server/test/integration/WebhookIntegrationTest.java +++ b/openvidu-server/src/test/java/io/openvidu/server/test/integration/WebhookIntegrationTest.java @@ -167,7 +167,7 @@ public class WebhookIntegrationTest { // Client should have already received "connectionCreated" RPC response // nonetheless - verify(sessionEventsHandler, times(1)).onParticipantJoined(refEq(participant), anyString(), anySet(), + verify(sessionEventsHandler, times(1)).onParticipantJoined(refEq(participant), anyString(), anyString(), anySet(), anyInt(), refEq(null)); // Now webhook response for event "participantJoined" should be received