'customSessionId' feature

pull/73/head
pabloFuente 2018-05-03 10:58:26 +02:00
parent 53830573fa
commit 0578753263
14 changed files with 257 additions and 171 deletions

View File

@ -29,15 +29,6 @@ import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturi
import platform = require('platform'); import platform = require('platform');
/**
* @hidden
*/
const SECRET_PARAM = '?secret=';
/**
* @hidden
*/
const RECORDER_PARAM = '&recorder=';
/** /**
* Entrypoint of OpenVidu Browser library. * Entrypoint of OpenVidu Browser library.
@ -46,11 +37,20 @@ const RECORDER_PARAM = '&recorder=';
export class OpenVidu { export class OpenVidu {
private session: Session; private session: Session;
private wsUri: string;
private secret = '';
private recorder = false;
private jsonRpcClient: any; private jsonRpcClient: any;
/**
* @hidden
*/
wsUri: string;
/**
* @hidden
*/
secret = '';
/**
* @hidden
*/
recorder = false;
/** /**
* @hidden * @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` * Returns a session with id `sessionId`
* @param sessionId Session unique ID generated in openvidu-server * @param sessionId Session unique ID generated in openvidu-server
*/ */
initSession(sessionId: string): Session { initSession(sessionId?: string): Session {
this.session = new Session(sessionId, this); 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; return this.session;
} }
@ -339,19 +353,6 @@ export class OpenVidu {
/* Hidden methods */ /* 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 * @hidden
*/ */
@ -524,21 +525,6 @@ export class OpenVidu {
this.jsonRpcClient.close(); 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 * @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;
}
} }

View File

@ -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 // 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 // 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 constraintsAux: MediaStreamConstraints = {};
const timeForDialogEvent = 1000; const timeForDialogEvent = 1250;
if (this.stream.isSendVideo()) { if (this.stream.isSendVideo()) {

View File

@ -81,10 +81,8 @@ export class Session implements EventDispatcher {
/** /**
* @hidden * @hidden
*/ */
constructor(sessionId: string, openvidu: OpenVidu) { constructor(openvidu: OpenVidu) {
this.openvidu = openvidu; this.openvidu = openvidu;
this.sessionId = this.openvidu.getUrlWithoutSecret(sessionId);
this.openvidu.processOpenViduUrl(sessionId);
} }
connect(token: string): Promise<any>; connect(token: string): Promise<any>;
@ -134,6 +132,9 @@ export class Session implements EventDispatcher {
/*return */new Promise((resolve, reject) => { /*return */new Promise((resolve, reject) => {
this.processToken(token);
if (this.openvidu.checkSystemRequirements()) { if (this.openvidu.checkSystemRequirements()) {
// Early configuration to deactivate automatic subscription to streams // Early configuration to deactivate automatic subscription to streams
this.options = { 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'); 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')) { 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'); location.assign(url + '/accept-certificate');
} }
@ -803,28 +804,32 @@ export class Session implements EventDispatcher {
forced = !!forced; forced = !!forced;
console.info('Leaving Session (forced=' + forced + ')'); console.info('Leaving Session (forced=' + forced + ')');
if (!!this.connection && !this.connection.disposed && !forced) { if (!!this.connection) {
this.openvidu.sendRequest('leaveRoom', (error, response) => { if (!this.connection.disposed && !forced) {
if (error) { this.openvidu.sendRequest('leaveRoom', (error, response) => {
console.error(error); if (error) {
} console.error(error);
}
this.openvidu.closeWs();
});
} else {
this.openvidu.closeWs(); 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 { } else {
this.openvidu.closeWs(); console.warn('You were not connected to the session ' + this.sessionId);
}
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();
} }
} }
@ -847,42 +852,46 @@ export class Session implements EventDispatcher {
}; };
this.openvidu.sendRequest('joinRoom', joinParams, (error, response) => { this.openvidu.sendRequest('joinRoom', joinParams, (error, response) => {
if (!!error) {
reject(error);
} else {
// Initialize local Connection object with values returned by openvidu-server // Initialize local Connection object with values returned by openvidu-server
this.connection = new Connection(this); this.connection = new Connection(this);
this.connection.connectionId = response.id; this.connection.connectionId = response.id;
this.connection.data = response.metadata; this.connection.data = response.metadata;
// Initialize remote Connections with value returned by openvidu-server // Initialize remote Connections with value returned by openvidu-server
const events = { const events = {
connections: new Array<Connection>(), connections: new Array<Connection>(),
streams: new Array<Stream>() streams: new Array<Stream>()
}; };
const existingParticipants: ConnectionOptions[] = response.value; const existingParticipants: ConnectionOptions[] = response.value;
existingParticipants.forEach(participant => { existingParticipants.forEach(participant => {
const connection = new Connection(this, participant); const connection = new Connection(this, participant);
this.remoteConnections[connection.connectionId] = connection; this.remoteConnections[connection.connectionId] = connection;
events.connections.push(connection); events.connections.push(connection);
if (!!connection.stream) { if (!!connection.stream) {
this.remoteStreamsCreated[connection.stream.streamId] = true; this.remoteStreamsCreated[connection.stream.streamId] = true;
events.streams.push(connection.stream); events.streams.push(connection.stream);
} }
}); });
// Own 'connectionCreated' event // Own 'connectionCreated' event
this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', this.connection, '')]); this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', this.connection, '')]);
// One 'connectionCreated' event for each existing connection in the session // One 'connectionCreated' event for each existing connection in the session
events.connections.forEach(connection => { events.connections.forEach(connection => {
this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', connection, '')]); this.ee.emitEvent('connectionCreated', [new ConnectionEvent(false, this, 'connectionCreated', connection, '')]);
}); });
// One 'streamCreated' event for each active stream in the session // One 'streamCreated' event for each active stream in the session
events.streams.forEach(stream => { events.streams.forEach(stream => {
this.ee.emitEvent('streamCreated', [new StreamEvent(false, this, 'streamCreated', 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 = <string>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';
}
} }

View File

@ -107,8 +107,9 @@ public class OpenVidu {
* @return The created session * @return The created session
* *
* @throws OpenViduJavaClientException * @throws OpenViduJavaClientException
* @throws OpenViduHttpException
*/ */
public Session createSession() throws OpenViduJavaClientException { public Session createSession() throws OpenViduJavaClientException, OpenViduHttpException {
Session s = new Session(myHttpClient, urlOpenViduServer); Session s = new Session(myHttpClient, urlOpenViduServer);
return s; return s;
} }
@ -122,8 +123,10 @@ public class OpenVidu {
* @return The created session * @return The created session
* *
* @throws OpenViduJavaClientException * @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); Session s = new Session(myHttpClient, urlOpenViduServer, properties);
return s; return s;
} }
@ -143,10 +146,11 @@ public class OpenVidu {
* @return The new created session * @return The new created session
* *
* @throws OpenViduJavaClientException * @throws OpenViduJavaClientException
* @throws OpenViduHttpException
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Recording startRecording(String sessionId, RecordingProperties properties) public Recording startRecording(String sessionId, RecordingProperties properties)
throws OpenViduJavaClientException { throws OpenViduJavaClientException, OpenViduHttpException {
HttpPost request = new HttpPost(this.urlOpenViduServer + API_RECORDINGS + API_RECORDINGS_START); 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)) { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
return new Recording(httpResponseToJson(response)); return new Recording(httpResponseToJson(response));
} else { } else {
throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); throw new OpenViduHttpException(statusCode);
} }
} }
@ -195,8 +199,10 @@ public class OpenVidu {
* guarantees * guarantees
* *
* @throws OpenViduJavaClientException * @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) { if (name == null) {
name = ""; name = "";
} }
@ -214,8 +220,9 @@ public class OpenVidu {
* guarantees * guarantees
* *
* @throws OpenViduJavaClientException * @throws OpenViduJavaClientException
* @throws OpenViduHttpException
*/ */
public Recording startRecording(String sessionId) throws OpenViduJavaClientException { public Recording startRecording(String sessionId) throws OpenViduJavaClientException, OpenViduHttpException {
return this.startRecording(sessionId, ""); return this.startRecording(sessionId, "");
} }
@ -228,8 +235,9 @@ public class OpenVidu {
* @return The stopped recording * @return The stopped recording
* *
* @throws OpenViduJavaClientException * @throws OpenViduJavaClientException
* @throws OpenViduHttpException
*/ */
public Recording stopRecording(String recordingId) throws OpenViduJavaClientException { public Recording stopRecording(String recordingId) throws OpenViduJavaClientException, OpenViduHttpException {
HttpPost request = new HttpPost( HttpPost request = new HttpPost(
this.urlOpenViduServer + API_RECORDINGS + API_RECORDINGS_STOP + "/" + recordingId); this.urlOpenViduServer + API_RECORDINGS + API_RECORDINGS_STOP + "/" + recordingId);
HttpResponse response; HttpResponse response;
@ -243,7 +251,7 @@ public class OpenVidu {
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
return new Recording(httpResponseToJson(response)); return new Recording(httpResponseToJson(response));
} else { } 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 * The id property of the recording you want to retrieve
* *
* @throws OpenViduJavaClientException * @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); HttpGet request = new HttpGet(this.urlOpenViduServer + API_RECORDINGS + "/" + recordingId);
HttpResponse response; HttpResponse response;
try { try {
@ -268,7 +277,7 @@ public class OpenVidu {
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) { if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
return new Recording(httpResponseToJson(response)); return new Recording(httpResponseToJson(response));
} else { } 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 * @return A {@link java.util.List} with all existing recordings
* *
* @throws OpenViduJavaClientException * @throws OpenViduJavaClientException
* @throws OpenViduHttpException
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<Recording> listRecordings() throws OpenViduJavaClientException { public List<Recording> listRecordings() throws OpenViduJavaClientException, OpenViduHttpException {
HttpGet request = new HttpGet(this.urlOpenViduServer + API_RECORDINGS); HttpGet request = new HttpGet(this.urlOpenViduServer + API_RECORDINGS);
HttpResponse response; HttpResponse response;
try { try {
@ -299,7 +309,7 @@ public class OpenVidu {
}); });
return recordings; return recordings;
} else { } else {
throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); throw new OpenViduHttpException(statusCode);
} }
} }
@ -311,8 +321,9 @@ public class OpenVidu {
* @param recordingId * @param recordingId
* *
* @throws OpenViduJavaClientException * @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); HttpDelete request = new HttpDelete(this.urlOpenViduServer + API_RECORDINGS + "/" + recordingId);
HttpResponse response; HttpResponse response;
try { try {
@ -323,7 +334,7 @@ public class OpenVidu {
int statusCode = response.getStatusLine().getStatusCode(); int statusCode = response.getStatusLine().getStatusCode();
if (!(statusCode == org.apache.http.HttpStatus.SC_NO_CONTENT)) { if (!(statusCode == org.apache.http.HttpStatus.SC_NO_CONTENT)) {
throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); throw new OpenViduHttpException(statusCode);
} }
} }

View File

@ -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;
}
}

View File

@ -40,7 +40,8 @@ public class Session {
final static String API_SESSIONS = "api/sessions"; final static String API_SESSIONS = "api/sessions";
final static String API_TOKENS = "api/tokens"; 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.httpClient = httpClient;
this.urlOpenViduServer = urlOpenViduServer; this.urlOpenViduServer = urlOpenViduServer;
this.properties = new SessionProperties(); this.properties = new SessionProperties();
@ -48,7 +49,7 @@ public class Session {
} }
protected Session(HttpClient httpClient, String urlOpenViduServer, SessionProperties properties) protected Session(HttpClient httpClient, String urlOpenViduServer, SessionProperties properties)
throws OpenViduJavaClientException { throws OpenViduJavaClientException, OpenViduHttpException {
this.httpClient = httpClient; this.httpClient = httpClient;
this.urlOpenViduServer = urlOpenViduServer; this.urlOpenViduServer = urlOpenViduServer;
this.properties = properties; this.properties = properties;
@ -72,8 +73,9 @@ public class Session {
* @returns The generated token * @returns The generated token
* *
* @throws OpenViduJavaClientException * @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()); return this.generateToken(new TokenOptions.Builder().role(OpenViduRole.PUBLISHER).build());
} }
@ -85,9 +87,10 @@ public class Session {
* @returns The generated token * @returns The generated token
* *
* @throws OpenViduJavaClientException * @throws OpenViduJavaClientException
* @throws OpenViduHttpException
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public String generateToken(TokenOptions tokenOptions) throws OpenViduJavaClientException { public String generateToken(TokenOptions tokenOptions) throws OpenViduJavaClientException, OpenViduHttpException {
if (!this.hasSessionId()) { if (!this.hasSessionId()) {
this.getSessionId(); this.getSessionId();
@ -121,7 +124,7 @@ public class Session {
System.out.println("Returning a TOKEN"); System.out.println("Returning a TOKEN");
return (String) httpResponseToJson(response).get("id"); return (String) httpResponseToJson(response).get("id");
} else { } else {
throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); throw new OpenViduHttpException(statusCode);
} }
} }
@ -142,7 +145,7 @@ public class Session {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void getSessionIdHttp() throws OpenViduJavaClientException { private void getSessionIdHttp() throws OpenViduJavaClientException, OpenViduHttpException {
if (this.hasSessionId()) { if (this.hasSessionId()) {
return; return;
} }
@ -154,6 +157,7 @@ public class Session {
json.put("recordingMode", properties.recordingMode().name()); json.put("recordingMode", properties.recordingMode().name());
json.put("defaultRecordingLayout", properties.defaultRecordingLayout().name()); json.put("defaultRecordingLayout", properties.defaultRecordingLayout().name());
json.put("defaultCustomLayout", properties.defaultCustomLayout()); json.put("defaultCustomLayout", properties.defaultCustomLayout());
json.put("customSessionId", properties.customSessionId());
StringEntity params = null; StringEntity params = null;
try { try {
params = new StringEntity(json.toString()); params = new StringEntity(json.toString());
@ -176,7 +180,7 @@ public class Session {
String id = (String) httpResponseToJson(response).get("id"); String id = (String) httpResponseToJson(response).get("id");
this.sessionId = id; this.sessionId = id;
} else { } else {
throw new OpenViduJavaClientException("Unexpected response from OpenVidu Server: " + statusCode); throw new OpenViduHttpException(statusCode);
} }
} }

View File

@ -23,6 +23,7 @@ public class SessionProperties {
private RecordingMode recordingMode; private RecordingMode recordingMode;
private RecordingLayout defaultRecordingLayout; private RecordingLayout defaultRecordingLayout;
private String defaultCustomLayout; private String defaultCustomLayout;
private String customSessionId;
/** /**
* Builder for {@link io.openvidu.java.client.SessionProperties} * Builder for {@link io.openvidu.java.client.SessionProperties}
@ -33,6 +34,7 @@ public class SessionProperties {
private RecordingMode recordingMode = RecordingMode.MANUAL; private RecordingMode recordingMode = RecordingMode.MANUAL;
private RecordingLayout defaultRecordingLayout = RecordingLayout.BEST_FIT; private RecordingLayout defaultRecordingLayout = RecordingLayout.BEST_FIT;
private String defaultCustomLayout = ""; private String defaultCustomLayout = "";
private String customSessionId = "";
/** /**
* Returns the {@link io.openvidu.java.client.SessionProperties} object properly * Returns the {@link io.openvidu.java.client.SessionProperties} object properly
@ -40,7 +42,7 @@ public class SessionProperties {
*/ */
public SessionProperties build() { public SessionProperties build() {
return new SessionProperties(this.mediaMode, this.recordingMode, this.defaultRecordingLayout, return new SessionProperties(this.mediaMode, this.recordingMode, this.defaultRecordingLayout,
this.defaultCustomLayout); this.defaultCustomLayout, this.customSessionId);
} }
/** /**
@ -96,6 +98,18 @@ public class SessionProperties {
return this; 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() { protected SessionProperties() {
@ -103,14 +117,16 @@ public class SessionProperties {
this.recordingMode = RecordingMode.MANUAL; this.recordingMode = RecordingMode.MANUAL;
this.defaultRecordingLayout = RecordingLayout.BEST_FIT; this.defaultRecordingLayout = RecordingLayout.BEST_FIT;
this.defaultCustomLayout = ""; this.defaultCustomLayout = "";
this.customSessionId = "";
} }
private SessionProperties(MediaMode mediaMode, RecordingMode recordingMode, RecordingLayout layout, private SessionProperties(MediaMode mediaMode, RecordingMode recordingMode, RecordingLayout layout,
String defaultCustomLayout) { String defaultCustomLayout, String customSessionId) {
this.mediaMode = mediaMode; this.mediaMode = mediaMode;
this.recordingMode = recordingMode; this.recordingMode = recordingMode;
this.defaultRecordingLayout = layout; this.defaultRecordingLayout = layout;
this.defaultCustomLayout = defaultCustomLayout; this.defaultCustomLayout = defaultCustomLayout;
this.customSessionId = customSessionId;
} }
/** /**
@ -156,4 +172,15 @@ public class SessionProperties {
return this.defaultCustomLayout; 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;
}
} }

View File

@ -48,7 +48,9 @@ export class OpenVidu {
/** /**
* Creates an OpenVidu session. You can call [[Session.getSessionId]] in the resolved promise to retrieve the `sessionId` * 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<Session> { public createSession(properties?: SessionProperties): Promise<Session> {
return new Promise<Session>((resolve, reject) => { return new Promise<Session>((resolve, reject) => {

View File

@ -116,7 +116,8 @@ export class Session {
mediaMode: !!this.properties.mediaMode ? this.properties.mediaMode : MediaMode.ROUTED, mediaMode: !!this.properties.mediaMode ? this.properties.mediaMode : MediaMode.ROUTED,
recordingMode: !!this.properties.recordingMode ? this.properties.recordingMode : RecordingMode.MANUAL, recordingMode: !!this.properties.recordingMode ? this.properties.recordingMode : RecordingMode.MANUAL,
defaultRecordingLayout: !!this.properties.defaultRecordingLayout ? this.properties.defaultRecordingLayout : RecordingLayout.BEST_FIT, 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 = { const options = {

View File

@ -43,4 +43,11 @@ export interface SessionProperties {
* You can easily override this value later by setting [[RecordingProperties.customLayout]] to any other value * You can easily override this value later by setting [[RecordingProperties.customLayout]] to any other value
*/ */
defaultCustomLayout?: string; 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;
} }

View File

@ -142,7 +142,7 @@ public class OpenViduServer implements JsonRpcConfigurer {
@Override @Override
public void registerJsonRpcHandlers(JsonRpcHandlerRegistry registry) { public void registerJsonRpcHandlers(JsonRpcHandlerRegistry registry) {
registry.addHandler(rpcHandler().withPingWatchdog(true), "/room"); registry.addHandler(rpcHandler().withPingWatchdog(true), "/openvidu");
} }
private static String getContainerIp() throws IOException, InterruptedException { private static String getContainerIp() throws IOException, InterruptedException {

View File

@ -93,6 +93,15 @@ public abstract class SessionManager {
public void evictParticipant(String participantPrivateId, String reason) throws OpenViduException { 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 * Returns a Session given its id
* *
@ -180,23 +189,19 @@ public abstract class SessionManager {
return null; return null;
} }
public String newSessionId(SessionProperties sessionProperties) { public void storeSessionId(String sessionId, SessionProperties sessionProperties) {
String sessionId = OpenViduServer.publicUrl;
sessionId += "/" + this.generateRandomChain();
this.sessionidTokenTokenobj.put(sessionId, new ConcurrentHashMap<>()); this.sessionidTokenTokenobj.put(sessionId, new ConcurrentHashMap<>());
this.sessionidParticipantpublicidParticipant.put(sessionId, new ConcurrentHashMap<>()); this.sessionidParticipantpublicidParticipant.put(sessionId, new ConcurrentHashMap<>());
this.sessionProperties.put(sessionId, sessionProperties); this.sessionProperties.put(sessionId, sessionProperties);
showTokens(); showTokens();
return sessionId;
} }
public String newToken(String sessionId, ParticipantRole role, String serverMetadata) throws OpenViduException { public String newToken(String sessionId, ParticipantRole role, String serverMetadata) throws OpenViduException {
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null
&& this.sessionidTokenTokenobj.get(sessionId) != null) { && this.sessionidTokenTokenobj.get(sessionId) != null) {
if (isMetadataFormatCorrect(serverMetadata)) { 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)); this.sessionidTokenTokenobj.get(sessionId).put(token, new Token(token, role, serverMetadata));
showTokens(); showTokens();
return token; return token;

View File

@ -477,7 +477,7 @@ public class ComposedRecordingService {
layout = layout.startsWith("/") ? layout.substring(1) : layout; layout = layout.startsWith("/") ? layout.substring(1) : layout;
layout = layout.endsWith("/") ? layout.substring(0, layout.length() - 1) : layout; layout = layout.endsWith("/") ? layout.substring(0, layout.length() - 1) : layout;
layout += "/index.html"; layout += "/index.html";
finalUrl = "https://OPENVIDUAPP:" + secret + "@" + location + "/layouts/custom/" + layout + "/?sessionId=" finalUrl = "https://OPENVIDUAPP:" + secret + "@" + location + "/layouts/custom/" + layout + "?sessionId="
+ shortSessionId + "&secret=" + secret; + shortSessionId + "&secret=" + secret;
} else { } else {
layout = recording.getRecordingLayout().name().toLowerCase().replaceAll("_", "-"); layout = recording.getRecordingLayout().name().toLowerCase().replaceAll("_", "-");

View File

@ -76,12 +76,16 @@ public class SessionRestController {
public ResponseEntity<JSONObject> getSessionId(@RequestBody(required = false) Map<?, ?> params) { public ResponseEntity<JSONObject> getSessionId(@RequestBody(required = false) Map<?, ?> params) {
SessionProperties.Builder builder = new SessionProperties.Builder(); SessionProperties.Builder builder = new SessionProperties.Builder();
String customSessionId = null;
if (params != null) { if (params != null) {
String mediaModeString = (String) params.get("mediaMode"); String mediaModeString = (String) params.get("mediaMode");
String recordingModeString = (String) params.get("recordingMode"); String recordingModeString = (String) params.get("recordingMode");
String defaultRecordingLayoutString = (String) params.get("defaultRecordingLayout"); String defaultRecordingLayoutString = (String) params.get("defaultRecordingLayout");
String defaultCustomLayout = (String) params.get("defaultCustomLayout"); String defaultCustomLayout = (String) params.get("defaultCustomLayout");
customSessionId = (String) params.get("customSessionId");
try { try {
// Safe parameter retrieval. Default values if not defined // Safe parameter retrieval. Default values if not defined
@ -114,7 +118,19 @@ public class SessionRestController {
SessionProperties sessionProperties = builder.build(); SessionProperties sessionProperties = builder.build();
String sessionId = sessionManager.newSessionId(sessionProperties); String sessionId;
if (customSessionId != null && !customSessionId.isEmpty()) {
if (sessionManager.sessionIdExists(customSessionId)) {
return new ResponseEntity<JSONObject>(HttpStatus.CONFLICT);
} else {
sessionId = customSessionId;
sessionManager.storeSessionId(sessionId, sessionProperties);
}
} else {
sessionId = sessionManager.generateRandomChain();
sessionManager.storeSessionId(sessionId, sessionProperties);
}
JSONObject responseJson = new JSONObject(); JSONObject responseJson = new JSONObject();
responseJson.put("id", sessionId); responseJson.put("id", sessionId);
return new ResponseEntity<>(responseJson, HttpStatus.OK); return new ResponseEntity<>(responseJson, HttpStatus.OK);
@ -203,8 +219,8 @@ public class SessionRestController {
customLayout = (customLayout == null) ? session.getSessionProperties().defaultCustomLayout() : customLayout; customLayout = (customLayout == null) ? session.getSessionProperties().defaultCustomLayout() : customLayout;
Recording startedRecording = this.recordingService.startRecording(session, Recording startedRecording = this.recordingService.startRecording(session, new RecordingProperties.Builder()
new RecordingProperties.Builder().name(name).recordingLayout(recordingLayout).customLayout(customLayout).build()); .name(name).recordingLayout(recordingLayout).customLayout(customLayout).build());
return new ResponseEntity<>(startedRecording.toJson(), HttpStatus.OK); return new ResponseEntity<>(startedRecording.toJson(), HttpStatus.OK);
} }