mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: new network quality e2e test
parent
c3d9fbb60e
commit
df0530d0a8
|
@ -140,7 +140,7 @@ node('container') {
|
|||
mvn --batch-mode versions:set-property -Dproperty=version.openvidu.java.client -DnewVersion=TEST
|
||||
mvn --batch-mode versions:set-property -Dproperty=version.openvidu.test.browsers -DnewVersion=TEST
|
||||
cd openvidu-test-e2e
|
||||
mvn -DskipTests=true clean compile
|
||||
mvn -DskipTests=true clean install
|
||||
sudo mvn --batch-mode -Dtest=OpenViduTestAppE2eTest -DAPP_URL=https://172.17.0.1:4200/ -DOPENVIDU_URL=https://172.17.0.1:4443/ -DREMOTE_URL_CHROME=http://172.17.0.1:6666/wd/hub/ -DREMOTE_URL_FIREFOX=http://172.17.0.1:6667/wd/hub/ -DEXTERNAL_CUSTOM_LAYOUT_URL=http://172.17.0.1:5555 -DEXTERNAL_CUSTOM_LAYOUT_PARAMS=sessionId,CUSTOM_LAYOUT_SESSION,secret,MY_SECRET test
|
||||
git checkout -f $OPENVIDU_COMMIT
|
||||
'''.stripIndent())
|
||||
|
|
|
@ -283,9 +283,8 @@ public class OpenViduEventManager {
|
|||
}
|
||||
|
||||
String[] events = rawEvents.replaceFirst("^<br>", "").split("<br>");
|
||||
JsonParser parser = new JsonParser();
|
||||
for (String e : events) {
|
||||
JsonObject event = (JsonObject) parser.parse(e);
|
||||
JsonObject event = JsonParser.parseString(e).getAsJsonObject();
|
||||
final String eventType = event.get("type").getAsString();
|
||||
|
||||
this.eventQueue.add(event);
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
package io.openvidu.test.e2e;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -36,6 +45,8 @@ import io.openvidu.test.browsers.utils.Unzipper;
|
|||
|
||||
public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
||||
|
||||
protected volatile static boolean isNetworkQualityTest;
|
||||
|
||||
@BeforeAll()
|
||||
protected static void setupAll() {
|
||||
checkFfmpegInstallation();
|
||||
|
@ -44,6 +55,29 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
cleanFoldersAndSetUpOpenViduJavaClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
@AfterEach
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
if (isNetworkQualityTest) {
|
||||
// Disable network quality API
|
||||
try {
|
||||
CustomHttpClient restClient = new CustomHttpClient(OPENVIDU_URL, "OPENVIDUAPP", OPENVIDU_SECRET);
|
||||
if (restClient.rest(HttpMethod.GET, "/openvidu/api/config", 200).get("OPENVIDU_PRO_NETWORK_QUALITY")
|
||||
.getAsBoolean()) {
|
||||
String body = "{'OPENVIDU_PRO_NETWORK_QUALITY':false}";
|
||||
restClient.rest(HttpMethod.POST, "/openvidu/api/restart", body, 200);
|
||||
waitUntilOpenViduRestarted(30);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
Assert.fail("Error restarting OpenVidu Server to disable Network quality API");
|
||||
} finally {
|
||||
isNetworkQualityTest = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Individual dynamic record")
|
||||
void individualDynamicRecordTest() throws Exception {
|
||||
|
@ -449,6 +483,9 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
@Test
|
||||
@DisplayName("openvidu-java-client PRO test")
|
||||
void openViduJavaClientProTest() throws Exception {
|
||||
|
||||
log.info("openvidu-java-client PRO test");
|
||||
|
||||
Session session = OV.createSession();
|
||||
Assert.assertFalse(session.fetch());
|
||||
Connection connection = session.createConnection();
|
||||
|
@ -462,4 +499,101 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Assert.assertFalse(session.fetch());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Network quality test")
|
||||
void networkQualityTest() throws Exception {
|
||||
|
||||
isNetworkQualityTest = true;
|
||||
|
||||
log.info("Network quality test");
|
||||
|
||||
CustomHttpClient restClient = new CustomHttpClient(OPENVIDU_URL, "OPENVIDUAPP", OPENVIDU_SECRET);
|
||||
String body = "{'OPENVIDU_PRO_NETWORK_QUALITY':true, 'OPENVIDU_PRO_NETWORK_QUALITY_INTERVAL':5}";
|
||||
restClient.rest(HttpMethod.POST, "/openvidu/api/restart", body, 200);
|
||||
waitUntilOpenViduRestarted(30);
|
||||
|
||||
setupBrowser("chrome");
|
||||
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||
user.getDriver().findElement(By.className("join-btn")).click();
|
||||
|
||||
user.getEventManager().waitUntilEventReaches("connectionCreated", 1);
|
||||
user.getEventManager().waitUntilEventReaches("streamPlaying", 1);
|
||||
JsonObject res = restClient.rest(HttpMethod.GET, "/openvidu/api/sessions/TestSession/connection",
|
||||
HttpStatus.SC_OK);
|
||||
final String connectionId = res.getAsJsonObject().get("content").getAsJsonArray().get(0).getAsJsonObject()
|
||||
.get("id").getAsString();
|
||||
|
||||
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .publish-checkbox")).click();
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .join-btn")).click();
|
||||
|
||||
final CountDownLatch latch1 = new CountDownLatch(1);
|
||||
Queue<Boolean> threadAssertions = new ConcurrentLinkedQueue<Boolean>();
|
||||
user.getEventManager().on("networkQualityLevelChanged", (event) -> {
|
||||
try {
|
||||
threadAssertions.add("networkQualityLevelChanged".equals(event.get("type").getAsString()));
|
||||
threadAssertions.add(event.get("oldValue") == null);
|
||||
threadAssertions.add(event.has("newValue") && event.get("newValue").getAsInt() > 0
|
||||
&& event.get("newValue").getAsInt() < 6);
|
||||
latch1.countDown();
|
||||
} catch (Exception e) {
|
||||
log.error("Error analysing NetworkQualityLevelChangedEvent: {}. {}", e.getCause(), e.getMessage());
|
||||
fail("Error analysing NetworkQualityLevelChangedEvent: " + e.getCause() + ". " + e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
user.getEventManager().waitUntilEventReaches("connectionCreated", 4);
|
||||
user.getEventManager().waitUntilEventReaches("streamPlaying", 2);
|
||||
user.getEventManager().waitUntilEventReaches("networkQualityLevelChanged", 2);
|
||||
|
||||
if (!latch1.await(30000, TimeUnit.MILLISECONDS)) {
|
||||
gracefullyLeaveParticipants(1);
|
||||
fail();
|
||||
return;
|
||||
}
|
||||
|
||||
user.getEventManager().off("networkQualityLevelChanged");
|
||||
log.info("Thread assertions: {}", threadAssertions.toString());
|
||||
for (Iterator<Boolean> iter = threadAssertions.iterator(); iter.hasNext();) {
|
||||
Assert.assertTrue("Some Event property was wrong", iter.next());
|
||||
iter.remove();
|
||||
}
|
||||
|
||||
// Both events should have publisher's connection ID
|
||||
Assert.assertTrue("Wrong connectionId in event NetworkQualityLevelChangedEvent", user.getDriver()
|
||||
.findElement(By.cssSelector("#openvidu-instance-0 .mat-expansion-panel:last-child .event-content"))
|
||||
.getAttribute("textContent").contains(connectionId));
|
||||
Assert.assertTrue("Wrong connectionId in event NetworkQualityLevelChangedEvent", user.getDriver()
|
||||
.findElement(By.cssSelector("#openvidu-instance-1 .mat-expansion-panel:last-child .event-content"))
|
||||
.getAttribute("textContent").contains(connectionId));
|
||||
|
||||
gracefullyLeaveParticipants(1);
|
||||
}
|
||||
|
||||
private void waitUntilOpenViduRestarted(int maxSecondsWait) throws Exception {
|
||||
boolean restarted = false;
|
||||
int msInterval = 500;
|
||||
int attempts = 0;
|
||||
final int maxAttempts = maxSecondsWait * 1000 / msInterval;
|
||||
Thread.sleep(500);
|
||||
while (!restarted && attempts < maxAttempts) {
|
||||
try {
|
||||
CustomHttpClient restClient = new CustomHttpClient(OPENVIDU_URL, "OPENVIDUAPP", OPENVIDU_SECRET);
|
||||
restClient.rest(HttpMethod.GET, "/openvidu/api/health", 200);
|
||||
restarted = true;
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
log.warn("Waiting for OpenVidu Server...");
|
||||
Thread.sleep(msInterval);
|
||||
} catch (InterruptedException e1) {
|
||||
log.error("Sleep interrupted");
|
||||
}
|
||||
attempts++;
|
||||
}
|
||||
}
|
||||
if (!restarted && attempts == maxAttempts) {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
</mat-form-field>
|
||||
|
||||
<div fxLayout="column" class="session-btns-div">
|
||||
<button mat-icon-button title="Session properties" [id]="'session-settings-btn-' + index" class="mat-icon-custom"
|
||||
(click)="openSessionPropertiesDialog()" [disabled]="session">
|
||||
<button mat-icon-button title="Session properties" [id]="'session-settings-btn-' + index"
|
||||
class="mat-icon-custom" (click)="openSessionPropertiesDialog()" [disabled]="session">
|
||||
<mat-icon class="mat-icon-custom-ic" aria-label="Session properties button">settings</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button title="Session API" [id]="'session-api-btn-' + index" class="mat-icon-custom"
|
||||
(click)="openSessionApiDialog()">
|
||||
<mat-icon class="mat-icon-custom-ic" aria-label="Session API button">cloud_circle</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button title="Session events" [id]="'session-events-btn-' + index" class="mat-icon-custom"
|
||||
(click)="openSessionEventsDialog()">
|
||||
<button mat-icon-button title="Session events" [id]="'session-events-btn-' + index"
|
||||
class="mat-icon-custom" (click)="openSessionEventsDialog()">
|
||||
<mat-icon class="mat-icon-custom-ic" aria-label="Session events button">notifications</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -36,8 +36,8 @@
|
|||
|
||||
<div class="join-publish-div">
|
||||
<button class="join-btn" mat-button (click)="joinSession()" [disabled]="session">JOIN</button>
|
||||
<mat-checkbox class="subscribe-checkbox" name="subscribeTo" (click)="toggleSubscribeTo()" [checked]="subscribeTo"
|
||||
[disabled]="session">Subscribe</mat-checkbox>
|
||||
<mat-checkbox class="subscribe-checkbox" name="subscribeTo" (click)="toggleSubscribeTo()"
|
||||
[checked]="subscribeTo" [disabled]="session">Subscribe</mat-checkbox>
|
||||
<mat-checkbox class="publish-checkbox" name="publishTo" (click)="togglePublishTo()" [checked]="publishTo"
|
||||
[disabled]="session">Publish</mat-checkbox>
|
||||
</div>
|
||||
|
@ -48,26 +48,32 @@
|
|||
<div>
|
||||
<h4>Send</h4>
|
||||
<div>
|
||||
<mat-checkbox class="send-audio-checkbox" name="sendAudio" (click)="toggleSendAudio()" [checked]="publisherProperties.audioSource !== false"
|
||||
[disabled]="session || !publishTo">Audio</mat-checkbox>
|
||||
<mat-checkbox class="send-video-checkbox" name="sendVideo" (click)="toggleSendVideo()" [checked]="publisherProperties.videoSource !== false"
|
||||
[disabled]="session || !publishTo">Video</mat-checkbox>
|
||||
<mat-checkbox class="send-audio-checkbox" name="sendAudio" (click)="toggleSendAudio()"
|
||||
[checked]="publisherProperties.audioSource !== false" [disabled]="session || !publishTo">Audio
|
||||
</mat-checkbox>
|
||||
<mat-checkbox class="send-video-checkbox" name="sendVideo" (click)="toggleSendVideo()"
|
||||
[checked]="publisherProperties.videoSource !== false" [disabled]="session || !publishTo">Video
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding-top: 5px;">
|
||||
<h4>Enter active</h4>
|
||||
<div>
|
||||
<mat-checkbox class="active-audio-checkbox" name="activeAudio" [(ngModel)]="publisherProperties.publishAudio"
|
||||
(click)="publisherProperties.publishAudio = !publisherProperties.publishAudio" [disabled]="session || !publishTo">Audio</mat-checkbox>
|
||||
<mat-checkbox class="active-video-checkbox" name="activeVideo" [(ngModel)]="publisherProperties.publishVideo"
|
||||
(click)="publisherProperties.publishVideo = !publisherProperties.publishVideo" [disabled]="session || !publishTo">Video</mat-checkbox>
|
||||
<mat-checkbox class="active-audio-checkbox" name="activeAudio"
|
||||
[(ngModel)]="publisherProperties.publishAudio"
|
||||
(click)="publisherProperties.publishAudio = !publisherProperties.publishAudio"
|
||||
[disabled]="session || !publishTo">Audio</mat-checkbox>
|
||||
<mat-checkbox class="active-video-checkbox" name="activeVideo"
|
||||
[(ngModel)]="publisherProperties.publishVideo"
|
||||
(click)="publisherProperties.publishVideo = !publisherProperties.publishVideo"
|
||||
[disabled]="session || !publishTo">Video</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div fxFlex="35">
|
||||
<mat-radio-group [(ngModel)]="optionsVideo" (change)="updateOptionsVideo($event)" [disabled]="session || !publishTo"
|
||||
[ngModelOptions]="{standalone: true}">
|
||||
<mat-radio-group [(ngModel)]="optionsVideo" (change)="updateOptionsVideo($event)"
|
||||
[disabled]="session || !publishTo" [ngModelOptions]="{standalone: true}">
|
||||
<div>
|
||||
<mat-radio-button class="video-radio" value="video">Video</mat-radio-button>
|
||||
</div>
|
||||
|
@ -75,15 +81,16 @@
|
|||
<mat-radio-button class="screen-radio" value="screen">Screen</mat-radio-button>
|
||||
</div>
|
||||
</mat-radio-group>
|
||||
<mat-checkbox class="subscribe-remote-check" name="subscribeToRemote" (click)="subscribeToRemote = !subscribeToRemote"
|
||||
[disabled]="!publishTo || session" [checked]="publishTo && subscribeToRemote">Subscribe
|
||||
<mat-checkbox class="subscribe-remote-check" name="subscribeToRemote"
|
||||
(click)="subscribeToRemote = !subscribeToRemote" [disabled]="!publishTo || session"
|
||||
[checked]="publishTo && subscribeToRemote">Subscribe
|
||||
<br>to remote</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<div fxFlex="10">
|
||||
<div fxLayout="column" class="publisher-btns-div">
|
||||
<button mat-icon-button title="Publisher properties" [id]="'publisher-settings-btn-' + index" class="mat-icon-custom"
|
||||
(click)="openPublisherPropertiesDialog()" [disabled]="!publishTo">
|
||||
<button mat-icon-button title="Publisher properties" [id]="'publisher-settings-btn-' + index"
|
||||
class="mat-icon-custom" (click)="openPublisherPropertiesDialog()" [disabled]="!publishTo">
|
||||
<mat-icon class="mat-icon-custom-ic" aria-label="Publisher properties button">settings</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button title="Add new publisher to running session" [id]="'session-api-btn-' + index"
|
||||
|
@ -107,7 +114,8 @@
|
|||
<div class="session-card-inner">
|
||||
<div class="session-title">{{sessionName}}</div>
|
||||
<div class="session-actions">
|
||||
<button *ngIf="republishPossible" class="republish-error-btn" (click)="republishAfterError()" title="Re publish">
|
||||
<button *ngIf="republishPossible" class="republish-error-btn" (click)="republishAfterError()"
|
||||
title="Re publish">
|
||||
<mat-icon aria-label="Re publish video" style="font-size: 20px">linked_camera</mat-icon>
|
||||
</button>
|
||||
<button class="message-btn" (click)="sendMessage()" title="Broadcast message">
|
||||
|
@ -136,8 +144,8 @@
|
|||
</div>
|
||||
<div [attr.id]="'remote-vid-' + session.connection.connectionId" fxFlex="240px" class="video-container">
|
||||
<div [attr.id]="'local-vid-' + session.connection.connectionId"></div>
|
||||
<app-video *ngIf="this.publisher" [streamManager]="this.publisher" [OV]="OV" [properties]="publisherProperties"
|
||||
(updateEventListInParent)="updateEventFromChild($event)">
|
||||
<app-video *ngIf="this.publisher" [streamManager]="this.publisher" [OV]="OV"
|
||||
[properties]="publisherProperties" (updateEventListInParent)="updateEventFromChild($event)">
|
||||
</app-video>
|
||||
<app-video *ngFor="let subscriber of this.subscribers" [streamManager]="subscriber" [OV]="OV"
|
||||
(updateEventListInParent)="updateEventFromChild($event)" (reSubbed)="updateSubscriberFromChild($event)">
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
import {
|
||||
OpenVidu, Session, Subscriber, Publisher, Event, StreamEvent, ConnectionEvent,
|
||||
SessionDisconnectedEvent, SignalEvent, RecordingEvent,
|
||||
PublisherSpeakingEvent, PublisherProperties, StreamPropertyChangedEvent, ConnectionPropertyChangedEvent, OpenViduError
|
||||
PublisherSpeakingEvent, PublisherProperties, StreamPropertyChangedEvent, ConnectionPropertyChangedEvent, OpenViduError, NetworkQualityLevelChangedEvent
|
||||
} from 'openvidu-browser';
|
||||
import {
|
||||
OpenVidu as OpenViduAPI,
|
||||
|
@ -116,6 +116,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
streamDestroyed: true,
|
||||
streamPropertyChanged: true,
|
||||
connectionPropertyChanged: true,
|
||||
networkQualityLevelChanged: true,
|
||||
recordingStarted: true,
|
||||
recordingStopped: true,
|
||||
signal: true,
|
||||
|
@ -225,6 +226,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
streamDestroyed: false,
|
||||
streamPropertyChanged: false,
|
||||
connectionPropertyChanged: false,
|
||||
networkQualityLevelChanged: false,
|
||||
recordingStarted: false,
|
||||
recordingStopped: false,
|
||||
signal: false,
|
||||
|
@ -383,6 +385,15 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.sessionEvents.networkQualityLevelChanged !== oldValues.networkQualityLevelChanged || firstTime) {
|
||||
this.session.off('networkQualityLevelChanged');
|
||||
if (this.sessionEvents.networkQualityLevelChanged) {
|
||||
this.session.on('networkQualityLevelChanged', (event: NetworkQualityLevelChangedEvent) => {
|
||||
this.updateEventList('networkQualityLevelChanged', event.connection.connectionId + ' [new:' + event.newValue + ',old:' + event.oldValue + ']', event);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sessionEvents.connectionCreated !== oldValues.connectionCreated || firstTime) {
|
||||
this.session.off('connectionCreated');
|
||||
if (this.sessionEvents.connectionCreated) {
|
||||
|
@ -638,6 +649,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
streamDestroyed: this.sessionEvents.streamDestroyed,
|
||||
streamPropertyChanged: this.sessionEvents.streamPropertyChanged,
|
||||
connectionPropertyChanged: this.sessionEvents.connectionPropertyChanged,
|
||||
networkQualityLevelChanged: this.sessionEvents.networkQualityLevelChanged,
|
||||
recordingStarted: this.sessionEvents.recordingStarted,
|
||||
recordingStopped: this.sessionEvents.recordingStopped,
|
||||
signal: this.sessionEvents.signal,
|
||||
|
@ -671,6 +683,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
|||
streamDestroyed: result.streamDestroyed,
|
||||
streamPropertyChanged: result.streamPropertyChanged,
|
||||
connectionPropertyChanged: result.connectionPropertyChanged,
|
||||
networkQualityLevelChanged: result.networkQualityLevelChanged,
|
||||
recordingStarted: result.recordingStarted,
|
||||
recordingStopped: result.recordingStopped,
|
||||
signal: result.signal,
|
||||
|
|
|
@ -38,7 +38,19 @@ export class TestSessionsComponent implements OnInit, OnDestroy {
|
|||
|
||||
this.eventsInfoSubscription = this.testFeedService.newLastEvent$.subscribe(
|
||||
newEvent => {
|
||||
(window as any).myEvents += ('<br>' + this.stringifyEventNoCircularDependencies(newEvent));
|
||||
const getCircularReplacer = () => {
|
||||
const seen = new WeakSet();
|
||||
return (key, value) => {
|
||||
if (typeof value === "object" && value !== null) {
|
||||
if (seen.has(value)) {
|
||||
return;
|
||||
}
|
||||
seen.add(value);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
};
|
||||
(window as any).myEvents += ('<br>' + JSON.stringify(newEvent, getCircularReplacer()));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -100,28 +112,4 @@ export class TestSessionsComponent implements OnInit, OnDestroy {
|
|||
this.loadSubs(subs);
|
||||
}
|
||||
|
||||
stringifyEventNoCircularDependencies(event: Event): string {
|
||||
const cache = [];
|
||||
return JSON.stringify(event, function (key, value) {
|
||||
if (key !== 'ee' && key !== 'openvidu') {
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
if (cache.indexOf(value) !== -1) {
|
||||
// Duplicate reference found
|
||||
try {
|
||||
// If this value does not reference a parent
|
||||
return JSON.parse(JSON.stringify(value));
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Store value in our collection
|
||||
cache.push(value);
|
||||
}
|
||||
return value;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue