diff --git a/openvidu-browser/src/OpenVidu/OpenVidu.ts b/openvidu-browser/src/OpenVidu/OpenVidu.ts index fa3d7f69..8f68cbc1 100644 --- a/openvidu-browser/src/OpenVidu/OpenVidu.ts +++ b/openvidu-browser/src/OpenVidu/OpenVidu.ts @@ -29,15 +29,6 @@ import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturi import platform = require('platform'); -/** - * @hidden - */ -const SECRET_PARAM = '?secret='; -/** - * @hidden - */ -const RECORDER_PARAM = '&recorder='; - /** * Entrypoint of OpenVidu Browser library. @@ -46,11 +37,20 @@ const RECORDER_PARAM = '&recorder='; export class OpenVidu { private session: Session; - private wsUri: string; - private secret = ''; - private recorder = false; private jsonRpcClient: any; + /** + * @hidden + */ + wsUri: string; + /** + * @hidden + */ + secret = ''; + /** + * @hidden + */ + recorder = false; /** * @hidden */ @@ -61,12 +61,26 @@ export class OpenVidu { } + initSession(): Session; + /** + * --- + * ## DEPRECATED + * + * _No `sessionId` is required. Now every necessary information is received in [[Session.connect]]_ + * + * --- + */ + initSession(sessionId: string): Session; + /** * Returns a session with id `sessionId` * @param sessionId Session unique ID generated in openvidu-server */ - initSession(sessionId: string): Session { - this.session = new Session(sessionId, this); + initSession(sessionId?: string): Session { + if (!!sessionId) { + console.warn("DEPRECATION WANING: In future releases 'OpenVidu.initSession' method won't require a parameter. Remove it (see http://openvidu.io/api/openvidu-browser/interfaces/publisherproperties.html)"); + } + this.session = new Session(this); return this.session; } @@ -339,19 +353,6 @@ export class OpenVidu { /* Hidden methods */ - /** - * @hidden - */ - getUrlWithoutSecret(url: string): string { - if (!url) { - console.error('sessionId is not defined'); - } - if (url.indexOf(SECRET_PARAM) !== -1) { - url = url.substring(0, url.lastIndexOf(SECRET_PARAM)); - } - return url; - } - /** * @hidden */ @@ -524,21 +525,6 @@ export class OpenVidu { this.jsonRpcClient.close(); } - /** - * @hidden - */ - processOpenViduUrl(url: string): void { - const secret = this.getSecretFromUrl(url); - const recorder = this.getRecorderFromUrl(url); - if (!!secret) { - this.secret = secret; - } - if (!!recorder) { - this.recorder = recorder; - } - this.wsUri = this.getFinalWsUrl(url); - } - /** * @hidden */ @@ -620,38 +606,4 @@ export class OpenVidu { } } - private getSecretFromUrl(url: string): string { - let secret = ''; - if (url.indexOf(SECRET_PARAM) !== -1) { - const endOfSecret = url.lastIndexOf(RECORDER_PARAM); - if (endOfSecret !== -1) { - secret = url.substring(url.lastIndexOf(SECRET_PARAM) + SECRET_PARAM.length, endOfSecret); - } else { - secret = url.substring(url.lastIndexOf(SECRET_PARAM) + SECRET_PARAM.length, url.length); - } - } - return secret; - } - - private getRecorderFromUrl(url: string): boolean { - let recorder = ''; - if (url.indexOf(RECORDER_PARAM) !== -1) { - recorder = url.substring(url.lastIndexOf(RECORDER_PARAM) + RECORDER_PARAM.length, url.length); - } - return Boolean(recorder).valueOf(); - } - - private getFinalWsUrl(url: string): string { - url = this.getUrlWithoutSecret(url).substring(0, url.lastIndexOf('/')) + '/room'; - if (url.indexOf('.ngrok.io') !== -1) { - // OpenVidu server URL referes to a ngrok IP: secure wss protocol and delete port of URL - url = url.replace('ws://', 'wss://'); - const regex = /\.ngrok\.io:\d+/; - url = url.replace(regex, '.ngrok.io'); - } else if ((url.indexOf('localhost') !== -1) || (url.indexOf('127.0.0.1') !== -1)) { - // OpenVidu server URL referes to localhost IP - } - return url; - } - } \ No newline at end of file diff --git a/openvidu-browser/src/OpenVidu/Publisher.ts b/openvidu-browser/src/OpenVidu/Publisher.ts index 3cdd6778..f0c566d7 100644 --- a/openvidu-browser/src/OpenVidu/Publisher.ts +++ b/openvidu-browser/src/OpenVidu/Publisher.ts @@ -337,7 +337,7 @@ export class Publisher implements EventDispatcher { // Ask independently for audio stream and video stream. If the user asks for both of them and one is blocked, the method still // success only with the allowed input. This is not the desierd behaviour: if any of them is blocked, access should be denied const constraintsAux: MediaStreamConstraints = {}; - const timeForDialogEvent = 1000; + const timeForDialogEvent = 1250; if (this.stream.isSendVideo()) { diff --git a/openvidu-browser/src/OpenVidu/Session.ts b/openvidu-browser/src/OpenVidu/Session.ts index 350b0da6..c292b1f5 100644 --- a/openvidu-browser/src/OpenVidu/Session.ts +++ b/openvidu-browser/src/OpenVidu/Session.ts @@ -81,10 +81,8 @@ export class Session implements EventDispatcher { /** * @hidden */ - constructor(sessionId: string, openvidu: OpenVidu) { + constructor(openvidu: OpenVidu) { this.openvidu = openvidu; - this.sessionId = this.openvidu.getUrlWithoutSecret(sessionId); - this.openvidu.processOpenViduUrl(sessionId); } connect(token: string): Promise; @@ -134,6 +132,9 @@ export class Session implements EventDispatcher { /*return */new Promise((resolve, reject) => { + + this.processToken(token); + if (this.openvidu.checkSystemRequirements()) { // Early configuration to deactivate automatic subscription to streams this.options = { @@ -745,7 +746,7 @@ export class Session implements EventDispatcher { console.warn('Not connected to session: if you are not debugging, this is probably a certificate error'); - const url = 'https://' + this.openvidu.getWsUri().split('wss://')[1].split('/room')[0]; + const url = 'https://' + this.openvidu.getWsUri().split('wss://')[1].split('/openvidu')[0]; if (window.confirm('If you are not debugging, this is probably a certificate error at \"' + url + '\"\n\nClick OK to navigate and accept it')) { location.assign(url + '/accept-certificate'); } @@ -803,28 +804,32 @@ export class Session implements EventDispatcher { forced = !!forced; console.info('Leaving Session (forced=' + forced + ')'); - if (!!this.connection && !this.connection.disposed && !forced) { - this.openvidu.sendRequest('leaveRoom', (error, response) => { - if (error) { - console.error(error); - } + if (!!this.connection) { + if (!this.connection.disposed && !forced) { + this.openvidu.sendRequest('leaveRoom', (error, response) => { + if (error) { + console.error(error); + } + this.openvidu.closeWs(); + }); + } else { this.openvidu.closeWs(); - }); + } + + if (!!this.connection.stream) { + // Make Publisher object dispatch 'streamDestroyed' event (if there's a local stream) + this.connection.stream.disposeWebRtcPeer(); + this.connection.stream.emitEvent('stream-destroyed-by-disconnect', [reason]); + } + + if (!this.connection.disposed) { + // Make Session object dispatch 'sessionDisconnected' event (if it is not already disposed) + const sessionDisconnectEvent = new SessionDisconnectedEvent(this, reason); + this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); + sessionDisconnectEvent.callDefaultBehaviour(); + } } else { - this.openvidu.closeWs(); - } - - if (!!this.connection.stream) { - // Make Publisher object dispatch 'streamDestroyed' event (if there's a local stream) - this.connection.stream.disposeWebRtcPeer(); - this.connection.stream.emitEvent('stream-destroyed-by-disconnect', [reason]); - } - - if (!this.connection.disposed) { - // Make Session object dispatch 'sessionDisconnected' event (if it is not already disposed) - const sessionDisconnectEvent = new SessionDisconnectedEvent(this, reason); - this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]); - sessionDisconnectEvent.callDefaultBehaviour(); + console.warn('You were not connected to the session ' + this.sessionId); } } @@ -847,42 +852,46 @@ export class Session implements EventDispatcher { }; this.openvidu.sendRequest('joinRoom', joinParams, (error, response) => { + if (!!error) { + reject(error); + } else { - // Initialize local Connection object with values returned by openvidu-server - this.connection = new Connection(this); - this.connection.connectionId = response.id; - this.connection.data = response.metadata; + // Initialize local Connection object with values returned by openvidu-server + this.connection = new Connection(this); + this.connection.connectionId = response.id; + this.connection.data = response.metadata; - // Initialize remote Connections with value returned by openvidu-server - const events = { - connections: new Array(), - streams: new Array() - }; - const existingParticipants: ConnectionOptions[] = response.value; - existingParticipants.forEach(participant => { - const connection = new Connection(this, participant); - this.remoteConnections[connection.connectionId] = connection; - events.connections.push(connection); - if (!!connection.stream) { - this.remoteStreamsCreated[connection.stream.streamId] = true; - events.streams.push(connection.stream); - } - }); + // Initialize remote Connections with value returned by openvidu-server + const events = { + connections: new Array(), + streams: new Array() + }; + const existingParticipants: ConnectionOptions[] = response.value; + existingParticipants.forEach(participant => { + const connection = new Connection(this, participant); + this.remoteConnections[connection.connectionId] = connection; + events.connections.push(connection); + if (!!connection.stream) { + this.remoteStreamsCreated[connection.stream.streamId] = true; + events.streams.push(connection.stream); + } + }); - // Own 'connectionCreated' event - this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', this.connection, '')]); + // Own 'connectionCreated' event + this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', this.connection, '')]); - // One 'connectionCreated' event for each existing connection in the session - events.connections.forEach(connection => { - this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', connection, '')]); - }); + // One 'connectionCreated' event for each existing connection in the session + events.connections.forEach(connection => { + this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', connection, '')]); + }); - // One 'streamCreated' event for each active stream in the session - events.streams.forEach(stream => { - this.ee.emitEvent('streamCreated', [new StreamEvent(false, this, 'streamCreated', stream, '')]); - }); + // One 'streamCreated' event for each active stream in the session + events.streams.forEach(stream => { + this.ee.emitEvent('streamCreated', [new StreamEvent(false, this, 'streamCreated', stream, '')]); + }); - resolve(); + resolve(); + } }); } }); @@ -928,4 +937,20 @@ export class Session implements EventDispatcher { }); } + private processToken(token: string): void { + const url = new URL(token); + this.sessionId = url.searchParams.get('sessionId'); + const secret = url.searchParams.get('secret'); + const recorder = url.searchParams.get('recorder'); + + if (!!secret) { + this.openvidu.secret = secret; + } + if (!!recorder) { + this.openvidu.recorder = true; + } + + this.openvidu.wsUri = 'wss://' + url.host + '/openvidu'; + } + } \ No newline at end of file diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/OpenVidu.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/OpenVidu.java index c00aa331..32056f3f 100644 --- a/openvidu-java-client/src/main/java/io/openvidu/java/client/OpenVidu.java +++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/OpenVidu.java @@ -107,8 +107,9 @@ public class OpenVidu { * @return The created session * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public Session createSession() throws OpenViduJavaClientException { + public Session createSession() throws OpenViduJavaClientException, OpenViduHttpException { Session s = new Session(myHttpClient, urlOpenViduServer); return s; } @@ -122,8 +123,10 @@ public class OpenVidu { * @return The created session * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public Session createSession(SessionProperties properties) throws OpenViduJavaClientException { + public Session createSession(SessionProperties properties) + throws OpenViduJavaClientException, OpenViduHttpException { Session s = new Session(myHttpClient, urlOpenViduServer, properties); return s; } @@ -143,10 +146,11 @@ public class OpenVidu { * @return The new created session * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ @SuppressWarnings("unchecked") public Recording startRecording(String sessionId, RecordingProperties properties) - throws OpenViduJavaClientException { + throws OpenViduJavaClientException, OpenViduHttpException { HttpPost request = new HttpPost(this.urlOpenViduServer + API_RECORDINGS + API_RECORDINGS_START); @@ -176,7 +180,7 @@ public class OpenVidu { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) { return new Recording(httpResponseToJson(response)); } else { - throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); + throw new OpenViduHttpException(statusCode); } } @@ -195,8 +199,10 @@ public class OpenVidu { * guarantees * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public Recording startRecording(String sessionId, String name) throws OpenViduJavaClientException { + public Recording startRecording(String sessionId, String name) + throws OpenViduJavaClientException, OpenViduHttpException { if (name == null) { name = ""; } @@ -214,8 +220,9 @@ public class OpenVidu { * guarantees * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public Recording startRecording(String sessionId) throws OpenViduJavaClientException { + public Recording startRecording(String sessionId) throws OpenViduJavaClientException, OpenViduHttpException { return this.startRecording(sessionId, ""); } @@ -228,8 +235,9 @@ public class OpenVidu { * @return The stopped recording * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public Recording stopRecording(String recordingId) throws OpenViduJavaClientException { + public Recording stopRecording(String recordingId) throws OpenViduJavaClientException, OpenViduHttpException { HttpPost request = new HttpPost( this.urlOpenViduServer + API_RECORDINGS + API_RECORDINGS_STOP + "/" + recordingId); HttpResponse response; @@ -243,7 +251,7 @@ public class OpenVidu { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) { return new Recording(httpResponseToJson(response)); } else { - throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); + throw new OpenViduHttpException(statusCode); } } @@ -254,8 +262,9 @@ public class OpenVidu { * The id property of the recording you want to retrieve * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public Recording getRecording(String recordingId) throws OpenViduJavaClientException { + public Recording getRecording(String recordingId) throws OpenViduJavaClientException, OpenViduHttpException { HttpGet request = new HttpGet(this.urlOpenViduServer + API_RECORDINGS + "/" + recordingId); HttpResponse response; try { @@ -268,7 +277,7 @@ public class OpenVidu { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) { return new Recording(httpResponseToJson(response)); } else { - throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); + throw new OpenViduHttpException(statusCode); } } @@ -278,9 +287,10 @@ public class OpenVidu { * @return A {@link java.util.List} with all existing recordings * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ @SuppressWarnings("unchecked") - public List listRecordings() throws OpenViduJavaClientException { + public List listRecordings() throws OpenViduJavaClientException, OpenViduHttpException { HttpGet request = new HttpGet(this.urlOpenViduServer + API_RECORDINGS); HttpResponse response; try { @@ -299,7 +309,7 @@ public class OpenVidu { }); return recordings; } else { - throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); + throw new OpenViduHttpException(statusCode); } } @@ -311,8 +321,9 @@ public class OpenVidu { * @param recordingId * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public void deleteRecording(String recordingId) throws OpenViduJavaClientException { + public void deleteRecording(String recordingId) throws OpenViduJavaClientException, OpenViduHttpException { HttpDelete request = new HttpDelete(this.urlOpenViduServer + API_RECORDINGS + "/" + recordingId); HttpResponse response; try { @@ -323,7 +334,7 @@ public class OpenVidu { int statusCode = response.getStatusLine().getStatusCode(); if (!(statusCode == org.apache.http.HttpStatus.SC_NO_CONTENT)) { - throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); + throw new OpenViduHttpException(statusCode); } } diff --git a/openvidu-java-client/src/main/java/io/openvidu/java/client/OpenViduHttpException.java b/openvidu-java-client/src/main/java/io/openvidu/java/client/OpenViduHttpException.java new file mode 100644 index 00000000..c3775c9d --- /dev/null +++ b/openvidu-java-client/src/main/java/io/openvidu/java/client/OpenViduHttpException.java @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2017-2018 OpenVidu (http://openvidu.io/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.openvidu.java.client; + +/** + * Defines error responses from OpenVidu Server + */ +public class OpenViduHttpException extends Exception { + + private static final long serialVersionUID = 1L; + private int status; + + public OpenViduHttpException(int status) { + super(Integer.toString(status)); + } + + public int getStatus() { + return this.status; + } + +} 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 6bdb4cad..a2c76032 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 @@ -40,7 +40,8 @@ public class Session { final static String API_SESSIONS = "api/sessions"; final static String API_TOKENS = "api/tokens"; - protected Session(HttpClient httpClient, String urlOpenViduServer) throws OpenViduJavaClientException { + protected Session(HttpClient httpClient, String urlOpenViduServer) + throws OpenViduJavaClientException, OpenViduHttpException { this.httpClient = httpClient; this.urlOpenViduServer = urlOpenViduServer; this.properties = new SessionProperties(); @@ -48,7 +49,7 @@ public class Session { } protected Session(HttpClient httpClient, String urlOpenViduServer, SessionProperties properties) - throws OpenViduJavaClientException { + throws OpenViduJavaClientException, OpenViduHttpException { this.httpClient = httpClient; this.urlOpenViduServer = urlOpenViduServer; this.properties = properties; @@ -72,8 +73,9 @@ public class Session { * @returns The generated token * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ - public String generateToken() throws OpenViduJavaClientException { + public String generateToken() throws OpenViduJavaClientException, OpenViduHttpException { return this.generateToken(new TokenOptions.Builder().role(OpenViduRole.PUBLISHER).build()); } @@ -85,9 +87,10 @@ public class Session { * @returns The generated token * * @throws OpenViduJavaClientException + * @throws OpenViduHttpException */ @SuppressWarnings("unchecked") - public String generateToken(TokenOptions tokenOptions) throws OpenViduJavaClientException { + public String generateToken(TokenOptions tokenOptions) throws OpenViduJavaClientException, OpenViduHttpException { if (!this.hasSessionId()) { this.getSessionId(); @@ -121,7 +124,7 @@ public class Session { System.out.println("Returning a TOKEN"); return (String) httpResponseToJson(response).get("id"); } else { - throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); + throw new OpenViduHttpException(statusCode); } } @@ -142,7 +145,7 @@ public class Session { } @SuppressWarnings("unchecked") - private void getSessionIdHttp() throws OpenViduJavaClientException { + private void getSessionIdHttp() throws OpenViduJavaClientException, OpenViduHttpException { if (this.hasSessionId()) { return; } @@ -154,6 +157,7 @@ public class Session { json.put("recordingMode", properties.recordingMode().name()); json.put("defaultRecordingLayout", properties.defaultRecordingLayout().name()); json.put("defaultCustomLayout", properties.defaultCustomLayout()); + json.put("customSessionId", properties.customSessionId()); StringEntity params = null; try { params = new StringEntity(json.toString()); @@ -176,7 +180,7 @@ public class Session { String id = (String) httpResponseToJson(response).get("id"); this.sessionId = id; } else { - throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); + throw new OpenViduHttpException(statusCode); } } 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 5702be17..4817e2b2 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 @@ -23,6 +23,7 @@ public class SessionProperties { private RecordingMode recordingMode; private RecordingLayout defaultRecordingLayout; private String defaultCustomLayout; + private String customSessionId; /** * Builder for {@link io.openvidu.java.client.SessionProperties} @@ -33,6 +34,7 @@ public class SessionProperties { private RecordingMode recordingMode = RecordingMode.MANUAL; private RecordingLayout defaultRecordingLayout = RecordingLayout.BEST_FIT; private String defaultCustomLayout = ""; + private String customSessionId = ""; /** * Returns the {@link io.openvidu.java.client.SessionProperties} object properly @@ -40,7 +42,7 @@ public class SessionProperties { */ public SessionProperties build() { return new SessionProperties(this.mediaMode, this.recordingMode, this.defaultRecordingLayout, - this.defaultCustomLayout); + this.defaultCustomLayout, this.customSessionId); } /** @@ -96,6 +98,18 @@ public class SessionProperties { return this; } + /** + * Call this method to fix the sessionId that will be assigned to the session. + * You can take advantage of this property to facilitate the mapping between + * OpenVidu Server 'session' entities and your own 'session' entities. If this + * parameter is undefined or an empty string, OpenVidu Server will generate a + * random sessionId for you. + */ + public SessionProperties.Builder customSessionId(String customSessionId) { + this.customSessionId = customSessionId; + return this; + } + } protected SessionProperties() { @@ -103,14 +117,16 @@ public class SessionProperties { this.recordingMode = RecordingMode.MANUAL; this.defaultRecordingLayout = RecordingLayout.BEST_FIT; this.defaultCustomLayout = ""; + this.customSessionId = ""; } private SessionProperties(MediaMode mediaMode, RecordingMode recordingMode, RecordingLayout layout, - String defaultCustomLayout) { + String defaultCustomLayout, String customSessionId) { this.mediaMode = mediaMode; this.recordingMode = recordingMode; this.defaultRecordingLayout = layout; this.defaultCustomLayout = defaultCustomLayout; + this.customSessionId = customSessionId; } /** @@ -156,4 +172,15 @@ public class SessionProperties { return this.defaultCustomLayout; } + /** + * Fixes the value of the sessionId property of the Session. You can take + * advantage of this property to facilitate the mapping between OpenVidu Server + * 'session' entities and your own 'session' entities. If this parameter is + * undefined or an empty string, OpenVidu Server will generate a random + * sessionId for you. + */ + public String customSessionId() { + return this.customSessionId; + } + } \ No newline at end of file diff --git a/openvidu-node-client/src/OpenVidu.ts b/openvidu-node-client/src/OpenVidu.ts index 823583db..a336f79d 100644 --- a/openvidu-node-client/src/OpenVidu.ts +++ b/openvidu-node-client/src/OpenVidu.ts @@ -48,7 +48,9 @@ export class OpenVidu { /** * Creates an OpenVidu session. You can call [[Session.getSessionId]] in the resolved promise to retrieve the `sessionId` * - * @returns A Promise that is resolved to the [[Session]] if success and rejected with an Error object if not + * @returns A Promise that is resolved to the [[Session]] if success and rejected with an Error object if not. + * This Error object has as `message` property with the following values: + * - `409`: you are trying to assign an already-in-use custom sessionId to the session. See [[SessionProperties.customSessionId]] */ public createSession(properties?: SessionProperties): Promise { return new Promise((resolve, reject) => { diff --git a/openvidu-node-client/src/Session.ts b/openvidu-node-client/src/Session.ts index ffe14b91..25f62c64 100644 --- a/openvidu-node-client/src/Session.ts +++ b/openvidu-node-client/src/Session.ts @@ -116,7 +116,8 @@ export class Session { mediaMode: !!this.properties.mediaMode ? this.properties.mediaMode : MediaMode.ROUTED, recordingMode: !!this.properties.recordingMode ? this.properties.recordingMode : RecordingMode.MANUAL, defaultRecordingLayout: !!this.properties.defaultRecordingLayout ? this.properties.defaultRecordingLayout : RecordingLayout.BEST_FIT, - defaultCustomLayout: !!this.properties.defaultCustomLayout ? this.properties.defaultCustomLayout : '' + defaultCustomLayout: !!this.properties.defaultCustomLayout ? this.properties.defaultCustomLayout : '', + customSessionId: !!this.properties.customSessionId ? this.properties.customSessionId : '' }); const options = { diff --git a/openvidu-node-client/src/SessionProperties.ts b/openvidu-node-client/src/SessionProperties.ts index 883b42af..05203c82 100644 --- a/openvidu-node-client/src/SessionProperties.ts +++ b/openvidu-node-client/src/SessionProperties.ts @@ -43,4 +43,11 @@ export interface SessionProperties { * You can easily override this value later by setting [[RecordingProperties.customLayout]] to any other value */ defaultCustomLayout?: string; + + /** + * Fix the sessionId that will be assigned to the session with this parameter. You can take advantage of this property + * to facilitate the mapping between OpenVidu Server 'session' entities and your own 'session' entities. + * If this parameter is undefined or an empty string, OpenVidu Server will generate a random sessionId for you. + */ + customSessionId?: string; } diff --git a/openvidu-server/src/main/java/io/openvidu/server/OpenViduServer.java b/openvidu-server/src/main/java/io/openvidu/server/OpenViduServer.java index faa53114..ab4a9c74 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/OpenViduServer.java +++ b/openvidu-server/src/main/java/io/openvidu/server/OpenViduServer.java @@ -142,7 +142,7 @@ public class OpenViduServer implements JsonRpcConfigurer { @Override public void registerJsonRpcHandlers(JsonRpcHandlerRegistry registry) { - registry.addHandler(rpcHandler().withPingWatchdog(true), "/room"); + registry.addHandler(rpcHandler().withPingWatchdog(true), "/openvidu"); } private static String getContainerIp() throws IOException, InterruptedException { 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 64e36afb..066192b2 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 @@ -93,6 +93,15 @@ public abstract class SessionManager { public void evictParticipant(String participantPrivateId, String reason) throws OpenViduException { } + /** + * Returns whether a sessionId already exists or not + * + * @return boolean + */ + public boolean sessionIdExists(String sessionId) { + return sessionidTokenTokenobj.containsKey(sessionId); + } + /** * Returns a Session given its id * @@ -180,23 +189,19 @@ public abstract class SessionManager { return null; } - public String newSessionId(SessionProperties sessionProperties) { - String sessionId = OpenViduServer.publicUrl; - sessionId += "/" + this.generateRandomChain(); - + public void storeSessionId(String sessionId, SessionProperties sessionProperties) { this.sessionidTokenTokenobj.put(sessionId, new ConcurrentHashMap<>()); this.sessionidParticipantpublicidParticipant.put(sessionId, new ConcurrentHashMap<>()); this.sessionProperties.put(sessionId, sessionProperties); - showTokens(); - return sessionId; } public String newToken(String sessionId, ParticipantRole role, String serverMetadata) throws OpenViduException { if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null && this.sessionidTokenTokenobj.get(sessionId) != null) { if (isMetadataFormatCorrect(serverMetadata)) { - String token = this.generateRandomChain(); + String token = OpenViduServer.publicUrl + "?sessionId=" + sessionId + "&token="; + token += this.generateRandomChain(); this.sessionidTokenTokenobj.get(sessionId).put(token, new Token(token, role, serverMetadata)); showTokens(); return token; diff --git a/openvidu-server/src/main/java/io/openvidu/server/recording/ComposedRecordingService.java b/openvidu-server/src/main/java/io/openvidu/server/recording/ComposedRecordingService.java index a83bfa17..abfcd5cf 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/recording/ComposedRecordingService.java +++ b/openvidu-server/src/main/java/io/openvidu/server/recording/ComposedRecordingService.java @@ -477,7 +477,7 @@ public class ComposedRecordingService { layout = layout.startsWith("/") ? layout.substring(1) : layout; layout = layout.endsWith("/") ? layout.substring(0, layout.length() - 1) : layout; layout += "/index.html"; - finalUrl = "https://OPENVIDUAPP:" + secret + "@" + location + "/layouts/custom/" + layout + "/?sessionId=" + finalUrl = "https://OPENVIDUAPP:" + secret + "@" + location + "/layouts/custom/" + layout + "?sessionId=" + shortSessionId + "&secret=" + secret; } else { layout = recording.getRecordingLayout().name().toLowerCase().replaceAll("_", "-"); 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 717aa531..61e1221d 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 @@ -62,7 +62,7 @@ public class SessionRestController { @Autowired private ComposedRecordingService recordingService; - + @Autowired private OpenviduConfig openviduConfig; @@ -76,12 +76,16 @@ public class SessionRestController { public ResponseEntity getSessionId(@RequestBody(required = false) Map params) { SessionProperties.Builder builder = new SessionProperties.Builder(); + String customSessionId = null; + if (params != null) { String mediaModeString = (String) params.get("mediaMode"); String recordingModeString = (String) params.get("recordingMode"); String defaultRecordingLayoutString = (String) params.get("defaultRecordingLayout"); String defaultCustomLayout = (String) params.get("defaultCustomLayout"); + customSessionId = (String) params.get("customSessionId"); + try { // Safe parameter retrieval. Default values if not defined @@ -114,7 +118,19 @@ public class SessionRestController { SessionProperties sessionProperties = builder.build(); - String sessionId = sessionManager.newSessionId(sessionProperties); + String sessionId; + if (customSessionId != null && !customSessionId.isEmpty()) { + if (sessionManager.sessionIdExists(customSessionId)) { + return new ResponseEntity(HttpStatus.CONFLICT); + } else { + sessionId = customSessionId; + sessionManager.storeSessionId(sessionId, sessionProperties); + } + } else { + sessionId = sessionManager.generateRandomChain(); + sessionManager.storeSessionId(sessionId, sessionProperties); + } + JSONObject responseJson = new JSONObject(); responseJson.put("id", sessionId); return new ResponseEntity<>(responseJson, HttpStatus.OK); @@ -169,7 +185,7 @@ public class SessionRestController { // "session" parameter not found return new ResponseEntity(HttpStatus.BAD_REQUEST); } - + if (!this.openviduConfig.isRecordingModuleEnabled()) { // OpenVidu Server configuration property "openvidu.recording" is set to false return new ResponseEntity(HttpStatus.NOT_IMPLEMENTED); @@ -200,11 +216,11 @@ public class SessionRestController { } else { recordingLayout = RecordingLayout.valueOf(recordingLayoutString); } - + customLayout = (customLayout == null) ? session.getSessionProperties().defaultCustomLayout() : customLayout; - Recording startedRecording = this.recordingService.startRecording(session, - new RecordingProperties.Builder().name(name).recordingLayout(recordingLayout).customLayout(customLayout).build()); + Recording startedRecording = this.recordingService.startRecording(session, new RecordingProperties.Builder() + .name(name).recordingLayout(recordingLayout).customLayout(customLayout).build()); return new ResponseEntity<>(startedRecording.toJson(), HttpStatus.OK); }