mirror of https://github.com/OpenVidu/openvidu.git
openvidu-server: prepare parameterized Media Node reconnection timeout
parent
fbf04bc6a2
commit
594d9f92f9
|
@ -38,7 +38,6 @@ import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
import io.openvidu.java.client.IceServerProperties;
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.validator.routines.DomainValidator;
|
import org.apache.commons.validator.routines.DomainValidator;
|
||||||
|
@ -59,6 +58,7 @@ import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
|
||||||
|
import io.openvidu.java.client.IceServerProperties;
|
||||||
import io.openvidu.java.client.OpenViduRole;
|
import io.openvidu.java.client.OpenViduRole;
|
||||||
import io.openvidu.java.client.VideoCodec;
|
import io.openvidu.java.client.VideoCodec;
|
||||||
import io.openvidu.server.OpenViduServer;
|
import io.openvidu.server.OpenViduServer;
|
||||||
|
@ -469,6 +469,10 @@ public class OpenviduConfig {
|
||||||
return RequestMappings.FRONTEND_CE;
|
return RequestMappings.FRONTEND_CE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getReconnectionTimeout() {
|
||||||
|
return 2000000000;
|
||||||
|
}
|
||||||
|
|
||||||
// Properties management methods
|
// Properties management methods
|
||||||
|
|
||||||
public OpenviduConfig deriveWithAdditionalPropertiesSource(Map<String, ?> propertiesSource) {
|
public OpenviduConfig deriveWithAdditionalPropertiesSource(Map<String, ?> propertiesSource) {
|
||||||
|
@ -544,7 +548,7 @@ public class OpenviduConfig {
|
||||||
postProcessConfigProps();
|
postProcessConfigProps();
|
||||||
userConfigProps = new ArrayList<>(configProps.keySet());
|
userConfigProps = new ArrayList<>(configProps.keySet());
|
||||||
userConfigProps.removeAll(getNonUserProperties());
|
userConfigProps.removeAll(getNonUserProperties());
|
||||||
for (String notShowEmptyConfigKey: getNonPrintablePropertiesIfEmpty()) {
|
for (String notShowEmptyConfigKey : getNonPrintablePropertiesIfEmpty()) {
|
||||||
String value = configProps.get(notShowEmptyConfigKey);
|
String value = configProps.get(notShowEmptyConfigKey);
|
||||||
if (value == null || value.isEmpty() || value.equals(new JsonArray().toString())) {
|
if (value == null || value.isEmpty() || value.equals(new JsonArray().toString())) {
|
||||||
userConfigProps.remove(notShowEmptyConfigKey);
|
userConfigProps.remove(notShowEmptyConfigKey);
|
||||||
|
@ -902,7 +906,6 @@ public class OpenviduConfig {
|
||||||
addError(property, "Cannot be empty");
|
addError(property, "Cannot be empty");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
|
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
|
||||||
return Boolean.parseBoolean(value);
|
return Boolean.parseBoolean(value);
|
||||||
} else {
|
} else {
|
||||||
|
@ -914,7 +917,6 @@ public class OpenviduConfig {
|
||||||
protected Integer asNonNegativeInteger(String property) {
|
protected Integer asNonNegativeInteger(String property) {
|
||||||
try {
|
try {
|
||||||
Integer integerValue = Integer.parseInt(getValue(property));
|
Integer integerValue = Integer.parseInt(getValue(property));
|
||||||
|
|
||||||
if (integerValue < 0) {
|
if (integerValue < 0) {
|
||||||
addError(property, "Is not a non negative integer");
|
addError(property, "Is not a non negative integer");
|
||||||
}
|
}
|
||||||
|
@ -925,6 +927,29 @@ public class OpenviduConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Integer asOptionalNonNegativeInteger(String property, int min, int max) {
|
||||||
|
try {
|
||||||
|
String value = getValue(property);
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Integer integerValue = Integer.parseInt(getValue(property));
|
||||||
|
if (integerValue < 0) {
|
||||||
|
addError(property, "Is not a non negative integer");
|
||||||
|
}
|
||||||
|
if (integerValue < min) {
|
||||||
|
addError(property, "Must be >= " + min);
|
||||||
|
}
|
||||||
|
if (integerValue >= max) {
|
||||||
|
addError(property, "Must be < " + max);
|
||||||
|
}
|
||||||
|
return integerValue;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
addError(property, "Is not a non negative integer");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This method checks all types of Internet addresses (IPv4, IPv6 and Domains)
|
* This method checks all types of Internet addresses (IPv4, IPv6 and Domains)
|
||||||
*/
|
*/
|
||||||
|
@ -1191,7 +1216,7 @@ public class OpenviduConfig {
|
||||||
private IceServerProperties.Builder readIceServer(String property, String iceServerString) {
|
private IceServerProperties.Builder readIceServer(String property, String iceServerString) {
|
||||||
String url = null, username = null, credential = null, staticAuthSecret = null;
|
String url = null, username = null, credential = null, staticAuthSecret = null;
|
||||||
String[] iceServerPropList = iceServerString.split(",");
|
String[] iceServerPropList = iceServerString.split(",");
|
||||||
for (String iceServerProp: iceServerPropList) {
|
for (String iceServerProp : iceServerPropList) {
|
||||||
if (iceServerProp.startsWith("url=")) {
|
if (iceServerProp.startsWith("url=")) {
|
||||||
url = StringUtils.substringAfter(iceServerProp, "url=");
|
url = StringUtils.substringAfter(iceServerProp, "url=");
|
||||||
} else if (iceServerProp.startsWith("username=")) {
|
} else if (iceServerProp.startsWith("username=")) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class FixedOneKmsManager extends KmsManager {
|
||||||
throws Exception {
|
throws Exception {
|
||||||
KmsProperties firstProps = kmsProperties.get(0);
|
KmsProperties firstProps = kmsProperties.get(0);
|
||||||
KurentoClient kClient = null;
|
KurentoClient kClient = null;
|
||||||
Kms kms = new Kms(firstProps, loadManager, mediaNodeManager);
|
Kms kms = new Kms(firstProps, loadManager, this);
|
||||||
try {
|
try {
|
||||||
JsonRpcWSConnectionListener listener = this.generateKurentoConnectionListener(kms.getId());
|
JsonRpcWSConnectionListener listener = this.generateKurentoConnectionListener(kms.getId());
|
||||||
JsonRpcClientNettyWebSocket client = new JsonRpcClientNettyWebSocket(firstProps.getUri(), listener);
|
JsonRpcClientNettyWebSocket client = new JsonRpcClientNettyWebSocket(firstProps.getUri(), listener);
|
||||||
|
@ -90,15 +90,10 @@ public class FixedOneKmsManager extends KmsManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String removeMediaNodeUponCrash(String mediaNodeId) {
|
protected String removeMediaNodeUponCrash(String mediaNodeId, boolean followedByReconnection, String message) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean infiniteRetry() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void postConstructInitKurentoClients() {
|
protected void postConstructInitKurentoClients() {
|
||||||
|
|
|
@ -39,7 +39,6 @@ import com.google.gson.JsonObject;
|
||||||
import io.openvidu.java.client.RecordingProperties;
|
import io.openvidu.java.client.RecordingProperties;
|
||||||
import io.openvidu.server.core.MediaServer;
|
import io.openvidu.server.core.MediaServer;
|
||||||
import io.openvidu.server.kurento.core.KurentoSession;
|
import io.openvidu.server.kurento.core.KurentoSession;
|
||||||
import io.openvidu.server.utils.MediaNodeManager;
|
|
||||||
import io.openvidu.server.utils.RecordingUtils;
|
import io.openvidu.server.utils.RecordingUtils;
|
||||||
import io.openvidu.server.utils.UpdatableTimerTask;
|
import io.openvidu.server.utils.UpdatableTimerTask;
|
||||||
|
|
||||||
|
@ -65,7 +64,7 @@ public class Kms {
|
||||||
private MediaServer mediaServer;
|
private MediaServer mediaServer;
|
||||||
private UpdatableTimerTask clientReconnectTimer;
|
private UpdatableTimerTask clientReconnectTimer;
|
||||||
private LoadManager loadManager;
|
private LoadManager loadManager;
|
||||||
private MediaNodeManager mediaNodeManager;
|
private KmsManager kmsManager;
|
||||||
|
|
||||||
private boolean isFirstReconnectionAttempt = true;
|
private boolean isFirstReconnectionAttempt = true;
|
||||||
private AtomicBoolean isKurentoClientConnected = new AtomicBoolean(false);
|
private AtomicBoolean isKurentoClientConnected = new AtomicBoolean(false);
|
||||||
|
@ -76,7 +75,7 @@ public class Kms {
|
||||||
private Map<String, String> activeRecordings = new ConcurrentHashMap<>();
|
private Map<String, String> activeRecordings = new ConcurrentHashMap<>();
|
||||||
private AtomicLong activeComposedRecordings = new AtomicLong();
|
private AtomicLong activeComposedRecordings = new AtomicLong();
|
||||||
|
|
||||||
public Kms(KmsProperties props, LoadManager loadManager, MediaNodeManager mediaNodeManager) {
|
public Kms(KmsProperties props, LoadManager loadManager, KmsManager kmsManager) {
|
||||||
this.id = props.getId();
|
this.id = props.getId();
|
||||||
this.uri = props.getUri();
|
this.uri = props.getUri();
|
||||||
|
|
||||||
|
@ -90,7 +89,7 @@ public class Kms {
|
||||||
this.ip = url.getHost();
|
this.ip = url.getHost();
|
||||||
|
|
||||||
this.loadManager = loadManager;
|
this.loadManager = loadManager;
|
||||||
this.mediaNodeManager = mediaNodeManager;
|
this.kmsManager = kmsManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KurentoClient getKurentoClient() {
|
public KurentoClient getKurentoClient() {
|
||||||
|
@ -146,13 +145,13 @@ public class Kms {
|
||||||
this.isKurentoClientConnected.set(isConnected);
|
this.isKurentoClientConnected.set(isConnected);
|
||||||
if (isConnected) {
|
if (isConnected) {
|
||||||
this.setTimeOfKurentoClientConnection(timestamp);
|
this.setTimeOfKurentoClientConnection(timestamp);
|
||||||
this.mediaNodeManager.mediaNodeUsageRegistration(this, timestamp);
|
kmsManager.getMediaNodeManager().mediaNodeUsageRegistration(this, timestamp, kmsManager.getKmss());
|
||||||
if (this.mediaServer == null) {
|
if (this.mediaServer == null) {
|
||||||
this.fetchMediaServerType();
|
this.fetchMediaServerType();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setTimeOfKurentoClientDisconnection(timestamp);
|
this.setTimeOfKurentoClientDisconnection(timestamp);
|
||||||
this.mediaNodeManager.mediaNodeUsageDeregistration(this, timestamp);
|
kmsManager.getMediaNodeManager().mediaNodeUsageDeregistration(this, timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +200,7 @@ public class Kms {
|
||||||
if (RecordingUtils.IS_COMPOSED(properties.outputMode())) {
|
if (RecordingUtils.IS_COMPOSED(properties.outputMode())) {
|
||||||
this.activeComposedRecordings.decrementAndGet();
|
this.activeComposedRecordings.decrementAndGet();
|
||||||
}
|
}
|
||||||
this.mediaNodeManager.dropIdleMediaNode(this.id);
|
kmsManager.getMediaNodeManager().dropIdleMediaNode(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonObject toJson() {
|
public JsonObject toJson() {
|
||||||
|
|
|
@ -109,6 +109,11 @@ public abstract class KmsManager {
|
||||||
protected SessionManager sessionManager;
|
protected SessionManager sessionManager;
|
||||||
protected LoadManager loadManager;
|
protected LoadManager loadManager;
|
||||||
|
|
||||||
|
// Media Node reconnection cycle: 6 attempts, 2 times per second (3s total)
|
||||||
|
final int MAX_RECONNECT_TIME_MILLIS = 3000;
|
||||||
|
final int INTERVAL_WAIT_MS = 500;
|
||||||
|
final int RECONNECTION_LOOPS = MAX_RECONNECT_TIME_MILLIS / INTERVAL_WAIT_MS;
|
||||||
|
|
||||||
public KmsManager(SessionManager sessionManager, LoadManager loadManager) {
|
public KmsManager(SessionManager sessionManager, LoadManager loadManager) {
|
||||||
this.sessionManager = sessionManager;
|
this.sessionManager = sessionManager;
|
||||||
this.loadManager = loadManager;
|
this.loadManager = loadManager;
|
||||||
|
@ -167,6 +172,10 @@ public abstract class KmsManager {
|
||||||
return kmsLoads;
|
return kmsLoads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MediaNodeManager getMediaNodeManager() {
|
||||||
|
return this.mediaNodeManager;
|
||||||
|
}
|
||||||
|
|
||||||
protected JsonRpcWSConnectionListener generateKurentoConnectionListener(final String kmsId) {
|
protected JsonRpcWSConnectionListener generateKurentoConnectionListener(final String kmsId) {
|
||||||
return new JsonRpcWSConnectionListener() {
|
return new JsonRpcWSConnectionListener() {
|
||||||
|
|
||||||
|
@ -218,29 +227,28 @@ public abstract class KmsManager {
|
||||||
|
|
||||||
kms.setKurentoClientConnected(false);
|
kms.setKurentoClientConnected(false);
|
||||||
|
|
||||||
disconnectionHandler(kms);
|
disconnectionHandler(kms, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disconnectionHandler(Kms kms) {
|
private void disconnectionHandler(Kms kms, int reconnectionSecondsConsumed) {
|
||||||
// 6 attempts, 2 times per second (3 seconds total)
|
|
||||||
final int maxReconnectTimeMillis = 3000;
|
|
||||||
final int intervalWaitMs = 500;
|
|
||||||
final int loops = maxReconnectTimeMillis / intervalWaitMs;
|
|
||||||
final AtomicInteger iteration = new AtomicInteger(loops);
|
|
||||||
|
|
||||||
|
final AtomicInteger iteration = new AtomicInteger(RECONNECTION_LOOPS);
|
||||||
final long initTime = System.currentTimeMillis();
|
final long initTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
final int accumulatedTimeout = reconnectionSecondsConsumed + (MAX_RECONNECT_TIME_MILLIS / 1000);
|
||||||
|
|
||||||
final UpdatableTimerTask kurentoClientReconnectTimer = new UpdatableTimerTask(() -> {
|
final UpdatableTimerTask kurentoClientReconnectTimer = new UpdatableTimerTask(() -> {
|
||||||
if (iteration.decrementAndGet() < 0) {
|
if (iteration.decrementAndGet() < 0) {
|
||||||
|
|
||||||
kms.getKurentoClientReconnectTimer().cancelTimer();
|
kms.getKurentoClientReconnectTimer().cancelTimer();
|
||||||
|
boolean mustRetryReconnection = accumulatedTimeout < openviduConfig.getReconnectionTimeout();
|
||||||
|
|
||||||
if (kms.isFirstReconnectionAttempt()) {
|
if (kms.isFirstReconnectionAttempt()) {
|
||||||
|
|
||||||
log.error(
|
log.error(
|
||||||
"OpenVidu Server [{}] could not reconnect to Media Node {} with IP {} in {} seconds. Media Node crashed",
|
"OpenVidu Server [{}] could not reconnect to Media Node {} with IP {} in {} seconds. Media Node crashed",
|
||||||
kms.getKurentoClient().toString(), kms.getId(), kms.getIp(),
|
kms.getKurentoClient().toString(), kms.getId(), kms.getIp(),
|
||||||
(intervalWaitMs * loops / 1000));
|
(INTERVAL_WAIT_MS * RECONNECTION_LOOPS / 1000));
|
||||||
|
|
||||||
kms.setFirstReconnectionAttempt(false);
|
kms.setFirstReconnectionAttempt(false);
|
||||||
|
|
||||||
|
@ -251,8 +259,8 @@ public abstract class KmsManager {
|
||||||
.map(entry -> entry.getKey()).collect(Collectors.toUnmodifiableList());
|
.map(entry -> entry.getKey()).collect(Collectors.toUnmodifiableList());
|
||||||
|
|
||||||
// 1. Remove Media Node from cluster
|
// 1. Remove Media Node from cluster
|
||||||
log.warn("Removing Media Node {} with IP {} after crash", kms.getId(), kms.getIp());
|
String environmentId = removeMediaNodeUponCrash(kms.getId(), mustRetryReconnection,
|
||||||
String environmentId = removeMediaNodeUponCrash(kms.getId());
|
"Removing Media Node " + kms.getId() + " after node crash");
|
||||||
|
|
||||||
// 2. Send nodeCrashed webhook event
|
// 2. Send nodeCrashed webhook event
|
||||||
sessionEventsHandler.onMediaNodeCrashed(kms, environmentId, timeOfKurentoDisconnection,
|
sessionEventsHandler.onMediaNodeCrashed(kms, environmentId, timeOfKurentoDisconnection,
|
||||||
|
@ -274,17 +282,27 @@ public abstract class KmsManager {
|
||||||
log.error(
|
log.error(
|
||||||
"Retry error. OpenVidu Server [{}] could not connect to Media Node {} with IP {} in {} seconds",
|
"Retry error. OpenVidu Server [{}] could not connect to Media Node {} with IP {} in {} seconds",
|
||||||
kms.getKurentoClient().toString(), kms.getId(), kms.getIp(),
|
kms.getKurentoClient().toString(), kms.getId(), kms.getIp(),
|
||||||
(intervalWaitMs * loops / 1000));
|
(INTERVAL_WAIT_MS * RECONNECTION_LOOPS / 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infiniteRetry()) {
|
if (mustRetryReconnection) {
|
||||||
log.info("Retrying reconnection to Media Node {} with IP {}", kms.getId(), kms.getIp());
|
log.info(
|
||||||
disconnectionHandler(kms);
|
"Retrying reconnection to Media Node {} with IP {}. {} seconds consumed of a maximum of {}",
|
||||||
|
kms.getId(), kms.getIp(), accumulatedTimeout,
|
||||||
|
openviduConfig.getReconnectionTimeout());
|
||||||
|
disconnectionHandler(kms, accumulatedTimeout);
|
||||||
|
} else {
|
||||||
|
log.warn(
|
||||||
|
"Reconnection process to Media Node {} with IP {} aborted. {} seconds have been consumed and the upper limit is {} seconds",
|
||||||
|
kms.getId(), kms.getIp(), accumulatedTimeout,
|
||||||
|
openviduConfig.getReconnectionTimeout());
|
||||||
|
removeMediaNodeUponCrash(kms.getId(), mustRetryReconnection, "Removing Media Node "
|
||||||
|
+ kms.getId() + " with IP " + kms.getIp() + " after reconnection abort");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ((System.currentTimeMillis() - initTime) > maxReconnectTimeMillis) {
|
if ((System.currentTimeMillis() - initTime) > MAX_RECONNECT_TIME_MILLIS) {
|
||||||
// KurentoClient connection timeout exceeds the limit. This prevents a
|
// KurentoClient connection timeout exceeds the limit. This prevents a
|
||||||
// single reconnection attempt to exceed the total timeout limit
|
// single reconnection attempt to exceed the total timeout limit
|
||||||
iteration.set(0);
|
iteration.set(0);
|
||||||
|
@ -329,7 +347,7 @@ public abstract class KmsManager {
|
||||||
|
|
||||||
kms.setTimeOfKurentoClientDisconnection(0);
|
kms.setTimeOfKurentoClientDisconnection(0);
|
||||||
}
|
}
|
||||||
}, () -> Long.valueOf(intervalWaitMs)); // Try 2 times per seconds
|
}, () -> Long.valueOf(INTERVAL_WAIT_MS)); // Try 2 times per second
|
||||||
|
|
||||||
kms.setKurentoClientReconnectTimer(kurentoClientReconnectTimer);
|
kms.setKurentoClientReconnectTimer(kurentoClientReconnectTimer);
|
||||||
kurentoClientReconnectTimer.updateTimer();
|
kurentoClientReconnectTimer.updateTimer();
|
||||||
|
@ -359,13 +377,12 @@ public abstract class KmsManager {
|
||||||
public abstract void decrementActiveRecordings(RecordingProperties recordingProperties, String recordingId,
|
public abstract void decrementActiveRecordings(RecordingProperties recordingProperties, String recordingId,
|
||||||
Session session);
|
Session session);
|
||||||
|
|
||||||
protected abstract String removeMediaNodeUponCrash(String mediaNodeId);
|
protected abstract String removeMediaNodeUponCrash(String mediaNodeId, boolean followedByReconnection,
|
||||||
|
String message);
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected abstract void postConstructInitKurentoClients();
|
protected abstract void postConstructInitKurentoClients();
|
||||||
|
|
||||||
protected abstract boolean infiniteRetry();
|
|
||||||
|
|
||||||
public void closeAllKurentoClients() {
|
public void closeAllKurentoClients() {
|
||||||
log.info("Closing all KurentoClients");
|
log.info("Closing all KurentoClients");
|
||||||
this.kmss.values().forEach(kms -> {
|
this.kmss.values().forEach(kms -> {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package io.openvidu.server.utils;
|
package io.openvidu.server.utils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import io.openvidu.server.kurento.kms.Kms;
|
import io.openvidu.server.kurento.kms.Kms;
|
||||||
|
|
||||||
public interface MediaNodeManager {
|
public interface MediaNodeManager {
|
||||||
|
|
||||||
public void mediaNodeUsageRegistration(Kms kms, long timeOfConnection);
|
public void mediaNodeUsageRegistration(Kms kms, long timeOfConnection, Collection<Kms> existingKmss);
|
||||||
|
|
||||||
public void mediaNodeUsageDeregistration(Kms kms, long timeOfDisconnection);
|
public void mediaNodeUsageDeregistration(Kms kms, long timeOfDisconnection);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package io.openvidu.server.utils;
|
package io.openvidu.server.utils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import io.openvidu.server.kurento.kms.Kms;
|
import io.openvidu.server.kurento.kms.Kms;
|
||||||
|
|
||||||
public class MediaNodeManagerDummy implements MediaNodeManager {
|
public class MediaNodeManagerDummy implements MediaNodeManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mediaNodeUsageRegistration(Kms kms, long timeOfConnection) {
|
public void mediaNodeUsageRegistration(Kms kms, long timeOfConnection, Collection<Kms> existingKmss) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue