diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java
index ccf65b2f..13dd609e 100644
--- a/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java
+++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/Session.java
@@ -661,17 +661,9 @@ public class Session {
}
HttpPost request = new HttpPost(this.openVidu.hostname + OpenVidu.API_SESSIONS);
-
- JsonObject json = new JsonObject();
- json.addProperty("mediaMode", properties.mediaMode().name());
- json.addProperty("recordingMode", properties.recordingMode().name());
- json.addProperty("defaultOutputMode", properties.defaultOutputMode().name());
- json.addProperty("defaultRecordingLayout", properties.defaultRecordingLayout().name());
- json.addProperty("defaultCustomLayout", properties.defaultCustomLayout());
- json.addProperty("customSessionId", properties.customSessionId());
StringEntity params = null;
try {
- params = new StringEntity(json.toString());
+ params = new StringEntity(properties.toJson().toString());
} catch (UnsupportedEncodingException e1) {
throw new OpenViduJavaClientException(e1.getMessage(), e1.getCause());
}
diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java
index 820c45ff..1305a0ab 100644
--- a/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java
+++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/SessionProperties.java
@@ -17,6 +17,8 @@
package io.openvidu.java.client;
+import com.google.gson.JsonObject;
+
import io.openvidu.java.client.Recording.OutputMode;
/**
@@ -261,4 +263,20 @@ public class SessionProperties {
return this.mediaNode;
}
+ protected JsonObject toJson() {
+ JsonObject json = new JsonObject();
+ json.addProperty("mediaMode", mediaMode().name());
+ json.addProperty("recordingMode", recordingMode().name());
+ json.addProperty("defaultOutputMode", defaultOutputMode().name());
+ json.addProperty("defaultRecordingLayout", defaultRecordingLayout().name());
+ json.addProperty("defaultCustomLayout", defaultCustomLayout());
+ json.addProperty("customSessionId", customSessionId());
+ if (mediaNode() != null) {
+ JsonObject mediaNodeJson = new JsonObject();
+ mediaNodeJson.addProperty("id", mediaNode());
+ json.add("mediaNode", mediaNodeJson);
+ }
+ return json;
+ }
+
}
\ No newline at end of file
diff --git a/openvidu-node-client/src/Session.ts b/openvidu-node-client/src/Session.ts
index 3f92a1e8..a374c1eb 100644
--- a/openvidu-node-client/src/Session.ts
+++ b/openvidu-node-client/src/Session.ts
@@ -465,7 +465,8 @@ export class Session {
defaultOutputMode: !!this.properties.defaultOutputMode ? this.properties.defaultOutputMode : Recording.OutputMode.COMPOSED,
defaultRecordingLayout: !!this.properties.defaultRecordingLayout ? this.properties.defaultRecordingLayout : RecordingLayout.BEST_FIT,
defaultCustomLayout: !!this.properties.defaultCustomLayout ? this.properties.defaultCustomLayout : '',
- customSessionId: !!this.properties.customSessionId ? this.properties.customSessionId : ''
+ customSessionId: !!this.properties.customSessionId ? this.properties.customSessionId : '',
+ mediaNode: !!this.properties.mediaNode ? this.properties.mediaNode : undefined
});
axios.post(
diff --git a/openvidu-node-client/src/SessionProperties.ts b/openvidu-node-client/src/SessionProperties.ts
index e08aa0d0..3c2ad5ef 100644
--- a/openvidu-node-client/src/SessionProperties.ts
+++ b/openvidu-node-client/src/SessionProperties.ts
@@ -69,8 +69,11 @@ export interface SessionProperties {
* **This feature is part of OpenVidu Pro tier** PRO
*
* The Media Node where to host the session. The default option if this property is not defined is the less loaded
- * Media Node at the moment the first user joins the session.
+ * Media Node at the moment the first user joins the session. This object defines the following properties as Media Node selector:
+ * - `id`: Media Node unique identifier
*/
- mediaNode?: string;
+ mediaNode?: {
+ id: string;
+ }
}
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 c38ac353..0bcc6155 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
@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
@@ -445,38 +446,11 @@ public abstract class SessionManager {
log.info("Running non active sessions garbage collector...");
final long currentMillis = System.currentTimeMillis();
- // Loop through all non active sessions. Safely remove them and clean all of
- // their data if their threshold has elapsed
- for (Iterator> iter = sessionsNotActive.entrySet().iterator(); iter.hasNext();) {
- final Session sessionNotActive = iter.next().getValue();
- final String sessionId = sessionNotActive.getSessionId();
- long sessionExistsSince = currentMillis - sessionNotActive.getStartTime();
- if (sessionExistsSince > (openviduConfig.getSessionGarbageThreshold() * 1000)) {
- try {
- if (sessionNotActive.closingLock.writeLock().tryLock(15, TimeUnit.SECONDS)) {
- try {
- if (sessions.containsKey(sessionId)) {
- // The session passed to active during lock wait
- continue;
- }
- iter.remove();
- cleanCollections(sessionId);
- log.info("Non active session {} cleaned up by garbage collector", sessionId);
- } finally {
- sessionNotActive.closingLock.writeLock().unlock();
- }
- } else {
- log.error(
- "Timeout waiting for Session closing lock to be available for garbage collector to clean session {}",
- sessionId);
- }
- } catch (InterruptedException e) {
- log.error(
- "InterruptedException while waiting for Session closing lock to be available for garbage collector to clean session {}",
- sessionId);
- }
- }
- }
+ this.closeNonActiveSessions(sessionNotActive -> {
+ // Remove non active session if threshold has elapsed
+ return (currentMillis - sessionNotActive.getStartTime()) > (openviduConfig.getSessionGarbageThreshold()
+ * 1000);
+ });
// Warn about possible ghost sessions
for (Iterator> iter = sessions.entrySet().iterator(); iter.hasNext();) {
@@ -550,6 +524,40 @@ public abstract class SessionManager {
}
}
+ public void closeNonActiveSessions(Function conditionToRemove) {
+ // Loop through all non active sessions. Safely remove and clean all of
+ // the data for each non active session meeting the condition
+ for (Iterator> iter = sessionsNotActive.entrySet().iterator(); iter.hasNext();) {
+ final Session sessionNotActive = iter.next().getValue();
+ final String sessionId = sessionNotActive.getSessionId();
+ if (conditionToRemove.apply(sessionNotActive)) {
+ try {
+ if (sessionNotActive.closingLock.writeLock().tryLock(15, TimeUnit.SECONDS)) {
+ try {
+ if (sessions.containsKey(sessionId)) {
+ // The session passed to active during lock wait
+ continue;
+ }
+ iter.remove();
+ cleanCollections(sessionId);
+ log.info("Non active session {} cleaned up", sessionId);
+ } finally {
+ sessionNotActive.closingLock.writeLock().unlock();
+ }
+ } else {
+ log.error(
+ "Timeout waiting for Session closing lock to be available to clean up non active session {}",
+ sessionId);
+ }
+ } catch (InterruptedException e) {
+ log.error(
+ "InterruptedException while waiting for non active Session closing lock to be available to clean up non active session session {}",
+ sessionId);
+ }
+ }
+ }
+ }
+
public void closeSessionAndEmptyCollections(Session session, EndReason reason, boolean stopRecording) {
if (openviduConfig.isRecordingModuleEnabled()) {