mirror of https://github.com/OpenVidu/openvidu.git
openvidu SDKs: support for updateConnection
parent
f2c37f29a5
commit
08fcdbdb15
|
@ -20,6 +20,10 @@ package io.openvidu.java.client;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link io.openvidu.java.client.Session#getActiveConnections()}
|
* See {@link io.openvidu.java.client.Session#getActiveConnections()}
|
||||||
|
@ -28,35 +32,52 @@ public class Connection {
|
||||||
|
|
||||||
private String connectionId;
|
private String connectionId;
|
||||||
private long createdAt;
|
private long createdAt;
|
||||||
private OpenViduRole role;
|
|
||||||
private String token;
|
|
||||||
private String location;
|
private String location;
|
||||||
private String platform;
|
private String platform;
|
||||||
private String serverData;
|
|
||||||
private String clientData;
|
private String clientData;
|
||||||
|
private Token token;
|
||||||
|
|
||||||
protected Map<String, Publisher> publishers;
|
protected Map<String, Publisher> publishers = new ConcurrentHashMap<>();
|
||||||
protected List<String> subscribers;
|
protected List<String> subscribers = new ArrayList<>();
|
||||||
|
|
||||||
protected Connection(String connectionId, long createdAt, OpenViduRole role, String token, String location,
|
protected Connection(JsonObject json) {
|
||||||
String platform, String serverData, String clientData, Map<String, Publisher> publishers,
|
JsonArray jsonArrayPublishers = json.get("publishers").getAsJsonArray();
|
||||||
List<String> subscribers) {
|
jsonArrayPublishers.forEach(publisher -> {
|
||||||
this.connectionId = connectionId;
|
JsonObject pubJson = publisher.getAsJsonObject();
|
||||||
this.createdAt = createdAt;
|
JsonObject mediaOptions = pubJson.get("mediaOptions").getAsJsonObject();
|
||||||
this.role = role;
|
Publisher pub = new Publisher(pubJson.get("streamId").getAsString(), pubJson.get("createdAt").getAsLong(),
|
||||||
this.token = token;
|
mediaOptions.get("hasAudio").getAsBoolean(), mediaOptions.get("hasVideo").getAsBoolean(),
|
||||||
this.location = location;
|
mediaOptions.get("audioActive"), mediaOptions.get("videoActive"), mediaOptions.get("frameRate"),
|
||||||
this.platform = platform;
|
mediaOptions.get("typeOfVideo"), mediaOptions.get("videoDimensions"));
|
||||||
this.serverData = serverData;
|
this.publishers.put(pub.getStreamId(), pub);
|
||||||
this.clientData = clientData;
|
});
|
||||||
this.publishers = publishers;
|
|
||||||
this.subscribers = subscribers;
|
JsonArray jsonArraySubscribers = json.get("subscribers").getAsJsonArray();
|
||||||
|
jsonArraySubscribers.forEach(subscriber -> {
|
||||||
|
this.subscribers.add((subscriber.getAsJsonObject()).get("streamId").getAsString());
|
||||||
|
});
|
||||||
|
|
||||||
|
this.connectionId = json.get("connectionId").getAsString();
|
||||||
|
this.createdAt = json.get("createdAt").getAsLong();
|
||||||
|
|
||||||
|
this.location = json.get("location").getAsString();
|
||||||
|
this.platform = json.get("platform").getAsString();
|
||||||
|
this.clientData = json.get("clientData").getAsString();
|
||||||
|
|
||||||
|
String token = json.has("token") ? json.get("token").getAsString() : null;
|
||||||
|
OpenViduRole role = OpenViduRole.valueOf(json.get("role").getAsString());
|
||||||
|
String data = json.get("serverData").getAsString();
|
||||||
|
Boolean record = json.get("record").getAsBoolean();
|
||||||
|
|
||||||
|
TokenOptions tokenOptions = new TokenOptions(role, data, record, null);
|
||||||
|
this.token = new Token(token, this.connectionId, tokenOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the identifier of the connection. You can call
|
* Returns the identifier of the connection. You can call methods
|
||||||
* {@link io.openvidu.java.client.Session#forceDisconnect(String)} passing this
|
* {@link io.openvidu.java.client.Session#forceDisconnect(String)} or
|
||||||
* property as parameter
|
* {@link io.openvidu.java.client.Session#updateConnection(String, TokenOptions)}
|
||||||
|
* passing this property as parameter
|
||||||
*/
|
*/
|
||||||
public String getConnectionId() {
|
public String getConnectionId() {
|
||||||
return connectionId;
|
return connectionId;
|
||||||
|
@ -74,21 +95,41 @@ public class Connection {
|
||||||
* Returns the role of the connection
|
* Returns the role of the connection
|
||||||
*/
|
*/
|
||||||
public OpenViduRole getRole() {
|
public OpenViduRole getRole() {
|
||||||
return role;
|
return this.token.getRole();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the token associated to the connection
|
* Returns the data associated to the connection on the server-side. This value
|
||||||
|
* is set with {@link io.openvidu.java.client.TokenOptions.Builder#data(String)}
|
||||||
|
* when calling {@link io.openvidu.java.client.Session#generateToken()}
|
||||||
|
*/
|
||||||
|
public String getServerData() {
|
||||||
|
return this.token.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the streams published by this Connection will be recorded or not.
|
||||||
|
* This only affects <a href=
|
||||||
|
* "https://docs.openvidu.io/en/stable/advanced-features/recording#selecting-streams-to-be-recorded"
|
||||||
|
* target="_blank">INDIVIDUAL recording</a>.
|
||||||
|
*/
|
||||||
|
public boolean record() {
|
||||||
|
return this.token.record();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the token string associated to the connection
|
||||||
*/
|
*/
|
||||||
public String getToken() {
|
public String getToken() {
|
||||||
return token;
|
return this.token.getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank" style="display:
|
* <a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank"
|
||||||
* inline-block; background-color: rgb(0, 136, 170); color: white; font-weight:
|
* style="display: inline-block; background-color: rgb(0, 136, 170); color:
|
||||||
* bold; padding: 0px 5px; margin-right: 5px; border-radius: 3px; font-size:
|
* white; font-weight: bold; padding: 0px 5px; margin-right: 5px; border-radius:
|
||||||
* 13px; line-height:21px; font-family: Montserrat, sans-serif">PRO</a>
|
* 3px; font-size: 13px; line-height:21px; font-family: Montserrat,
|
||||||
|
* sans-serif">PRO</a>
|
||||||
*
|
*
|
||||||
* Returns the geo location of the connection, with the following format:
|
* Returns the geo location of the connection, with the following format:
|
||||||
* <code>"CITY, COUNTRY"</code> (<code>"unknown"</code> if it wasn't possible to
|
* <code>"CITY, COUNTRY"</code> (<code>"unknown"</code> if it wasn't possible to
|
||||||
|
@ -106,20 +147,11 @@ public class Connection {
|
||||||
return platform;
|
return platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the data associated to the connection on the server-side. This value
|
|
||||||
* is set with {@link io.openvidu.java.client.TokenOptions.Builder#data(String)}
|
|
||||||
* when calling {@link io.openvidu.java.client.Session#generateToken()}
|
|
||||||
*/
|
|
||||||
public String getServerData() {
|
|
||||||
return serverData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the data associated to the connection on the client-side. This value
|
* Returns the data associated to the connection on the client-side. This value
|
||||||
* is set with second parameter of method
|
* is set with second parameter of method <a href=
|
||||||
* <a href="https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html#connect" target
|
* "https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html#connect"
|
||||||
* ="_blank">Session.connect</a> in OpenVidu Browser
|
* target ="_blank">Session.connect</a> in OpenVidu Browser
|
||||||
*/
|
*/
|
||||||
public String getClientData() {
|
public String getClientData() {
|
||||||
return clientData;
|
return clientData;
|
||||||
|
@ -147,6 +179,16 @@ public class Connection {
|
||||||
return this.subscribers;
|
return this.subscribers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For now only properties data, role and record can be updated
|
||||||
|
*/
|
||||||
|
protected void overrideTokenOptions(TokenOptions tokenOptions) {
|
||||||
|
TokenOptions.Builder modifiableTokenOptions = new TokenOptions.Builder().role(tokenOptions.getRole())
|
||||||
|
.record(tokenOptions.record());
|
||||||
|
modifiableTokenOptions.data(this.token.getData());
|
||||||
|
this.token.overrideTokenOptions(modifiableTokenOptions.build());
|
||||||
|
}
|
||||||
|
|
||||||
protected void setSubscribers(List<String> subscribers) {
|
protected void setSubscribers(List<String> subscribers) {
|
||||||
this.subscribers = subscribers;
|
this.subscribers = subscribers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.http.HttpHeaders;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.HttpDelete;
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPatch;
|
||||||
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
|
@ -70,7 +71,7 @@ public class Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the unique identifier of the Session
|
* Gets the unique identifier of the Session.
|
||||||
*
|
*
|
||||||
* @return The sessionId
|
* @return The sessionId
|
||||||
*/
|
*/
|
||||||
|
@ -80,78 +81,112 @@ public class Session {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timestamp when this session was created, in UTC milliseconds (ms since Jan 1,
|
* Timestamp when this session was created, in UTC milliseconds (ms since Jan 1,
|
||||||
* 1970, 00:00:00 UTC)
|
* 1970, 00:00:00 UTC).
|
||||||
*/
|
*/
|
||||||
public long createdAt() {
|
public long createdAt() {
|
||||||
return this.createdAt;
|
return this.createdAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a new token associated to Session object with default values for
|
* @deprecated Use {@link Session#createToken() Session.createToken()} instead
|
||||||
* {@link io.openvidu.java.client.TokenOptions}. This always translates into a
|
* to get a {@link io.openvidu.java.client.Token} object.
|
||||||
* new request to OpenVidu Server
|
|
||||||
*
|
*
|
||||||
* @return The generated token
|
* @return The generated token String
|
||||||
*
|
*
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String generateToken() throws OpenViduJavaClientException, OpenViduHttpException {
|
public String generateToken() throws OpenViduJavaClientException, OpenViduHttpException {
|
||||||
return this.generateToken(new TokenOptions.Builder().role(OpenViduRole.PUBLISHER).build());
|
return createToken().getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a new token associated to Session object configured with
|
* @deprecated Use
|
||||||
* <code>tokenOptions</code>. This always translates into a new request to
|
* {@link Session#createToken(io.openvidu.java.client.TokenOptions)
|
||||||
* OpenVidu Server
|
* Session.createToken(TokenOptions)} instead to get a
|
||||||
|
* {@link io.openvidu.java.client.Token} object.
|
||||||
*
|
*
|
||||||
* @return The generated token
|
* @return The generated token String
|
||||||
*
|
*
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String generateToken(TokenOptions tokenOptions) throws OpenViduJavaClientException, OpenViduHttpException {
|
public String generateToken(TokenOptions tokenOptions) throws OpenViduJavaClientException, OpenViduHttpException {
|
||||||
|
return createToken(tokenOptions).getToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a new token object associated to Session object with default values for
|
||||||
|
* {@link io.openvidu.java.client.TokenOptions}. The token string value to send
|
||||||
|
* to the client side can be retrieved with
|
||||||
|
* {@link io.openvidu.java.client.Token#getToken() Token.getToken()}. <br>
|
||||||
|
* <br>
|
||||||
|
* You can use method {@link io.openvidu.java.client.Token#getConnectionId()
|
||||||
|
* Token.getConnectionId()} to get the connection identifier that will be given
|
||||||
|
* to the user consuming the token. With <code>connectionId</code> you can call
|
||||||
|
* the following methods without having to fetch and search for the actual
|
||||||
|
* {@link io.openvidu.java.client.Connection Connection} object:
|
||||||
|
* <ul>
|
||||||
|
* <li>Call {@link io.openvidu.java.client.Session#forceDisconnect(String)
|
||||||
|
* Session.forceDisconnect()} to invalidate the token if no client has used it
|
||||||
|
* yet or force the connected client to leave the session if it has.</li>
|
||||||
|
* <li>Call
|
||||||
|
* {@link io.openvidu.java.client.Session#updateConnection(String, TokenOptions)
|
||||||
|
* Session.updateConnection()} to update the
|
||||||
|
* {@link io.openvidu.java.client.Connection Connection} options. And this is
|
||||||
|
* valid for unused tokens, but also for already used tokens, so you can
|
||||||
|
* dynamically change the connection options on the fly.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return The generated {@link io.openvidu.java.client.Token Token} object.
|
||||||
|
*
|
||||||
|
* @throws OpenViduJavaClientException
|
||||||
|
* @throws OpenViduHttpException
|
||||||
|
*/
|
||||||
|
public Token createToken() throws OpenViduJavaClientException, OpenViduHttpException {
|
||||||
|
return createToken(new TokenOptions.Builder().data("").role(OpenViduRole.PUBLISHER).record(true).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a new token object associated to Session object configured with
|
||||||
|
* <code>tokenOptions</code>. The token string value to send to the client side
|
||||||
|
* can be retrieved with {@link io.openvidu.java.client.Token#getToken()
|
||||||
|
* Token.getToken()}. <br>
|
||||||
|
* <br>
|
||||||
|
* You can use method {@link io.openvidu.java.client.Token#getConnectionId()
|
||||||
|
* Token.getConnectionId()} to get the connection identifier that will be given
|
||||||
|
* to the user consuming the token. With <code>connectionId</code> you can call
|
||||||
|
* the following methods without having to fetch and search for the actual
|
||||||
|
* {@link io.openvidu.java.client.Connection Connection} object:
|
||||||
|
* <ul>
|
||||||
|
* <li>Call {@link io.openvidu.java.client.Session#forceDisconnect(String)
|
||||||
|
* Session.forceDisconnect()} to invalidate the token if no client has used it
|
||||||
|
* yet or force the connected client to leave the session if it has.</li>
|
||||||
|
* <li>Call
|
||||||
|
* {@link io.openvidu.java.client.Session#updateConnection(String, TokenOptions)
|
||||||
|
* Session.updateConnection()} to update the
|
||||||
|
* {@link io.openvidu.java.client.Connection Connection} options. And this is
|
||||||
|
* valid for unused tokens, but also for already used tokens, so you can
|
||||||
|
* dynamically change the user connection options on the fly.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return The generated {@link io.openvidu.java.client.Token Token} object.
|
||||||
|
*
|
||||||
|
* @throws OpenViduJavaClientException
|
||||||
|
* @throws OpenViduHttpException
|
||||||
|
*/
|
||||||
|
public Token createToken(TokenOptions tokenOptions) throws OpenViduJavaClientException, OpenViduHttpException {
|
||||||
if (!this.hasSessionId()) {
|
if (!this.hasSessionId()) {
|
||||||
this.getSessionId();
|
this.getSessionId();
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpPost request = new HttpPost(this.openVidu.hostname + OpenVidu.API_TOKENS);
|
HttpPost request = new HttpPost(this.openVidu.hostname + OpenVidu.API_TOKENS);
|
||||||
|
|
||||||
JsonObject json = new JsonObject();
|
|
||||||
json.addProperty("session", this.sessionId);
|
|
||||||
json.addProperty("role", tokenOptions.getRole().name());
|
|
||||||
json.addProperty("data", tokenOptions.getData());
|
|
||||||
if (tokenOptions.getKurentoOptions() != null) {
|
|
||||||
JsonObject kurentoOptions = new JsonObject();
|
|
||||||
if (tokenOptions.getKurentoOptions().getVideoMaxRecvBandwidth() != null) {
|
|
||||||
kurentoOptions.addProperty("videoMaxRecvBandwidth",
|
|
||||||
tokenOptions.getKurentoOptions().getVideoMaxRecvBandwidth());
|
|
||||||
}
|
|
||||||
if (tokenOptions.getKurentoOptions().getVideoMinRecvBandwidth() != null) {
|
|
||||||
kurentoOptions.addProperty("videoMinRecvBandwidth",
|
|
||||||
tokenOptions.getKurentoOptions().getVideoMinRecvBandwidth());
|
|
||||||
}
|
|
||||||
if (tokenOptions.getKurentoOptions().getVideoMaxSendBandwidth() != null) {
|
|
||||||
kurentoOptions.addProperty("videoMaxSendBandwidth",
|
|
||||||
tokenOptions.getKurentoOptions().getVideoMaxSendBandwidth());
|
|
||||||
}
|
|
||||||
if (tokenOptions.getKurentoOptions().getVideoMinSendBandwidth() != null) {
|
|
||||||
kurentoOptions.addProperty("videoMinSendBandwidth",
|
|
||||||
tokenOptions.getKurentoOptions().getVideoMinSendBandwidth());
|
|
||||||
}
|
|
||||||
if (tokenOptions.getKurentoOptions().getAllowedFilters().length > 0) {
|
|
||||||
JsonArray allowedFilters = new JsonArray();
|
|
||||||
for (String filter : tokenOptions.getKurentoOptions().getAllowedFilters()) {
|
|
||||||
allowedFilters.add(filter);
|
|
||||||
}
|
|
||||||
kurentoOptions.add("allowedFilters", allowedFilters);
|
|
||||||
}
|
|
||||||
json.add("kurentoOptions", kurentoOptions);
|
|
||||||
}
|
|
||||||
StringEntity params;
|
StringEntity params;
|
||||||
try {
|
try {
|
||||||
params = new StringEntity(json.toString());
|
params = new StringEntity(tokenOptions.toJsonObject(sessionId).toString());
|
||||||
} catch (UnsupportedEncodingException e1) {
|
} catch (UnsupportedEncodingException e1) {
|
||||||
throw new OpenViduJavaClientException(e1.getMessage(), e1.getCause());
|
throw new OpenViduJavaClientException(e1.getMessage(), e1.getCause());
|
||||||
}
|
}
|
||||||
|
@ -169,8 +204,8 @@ public class Session {
|
||||||
try {
|
try {
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
|
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
|
||||||
String token = httpResponseToJson(response).get("id").getAsString();
|
Token token = new Token(httpResponseToJson(response));
|
||||||
log.info("Returning a TOKEN: {}", token);
|
log.info("Returning a TOKEN: {}", token.getToken());
|
||||||
return token;
|
return token;
|
||||||
} else {
|
} else {
|
||||||
throw new OpenViduHttpException(statusCode);
|
throw new OpenViduHttpException(statusCode);
|
||||||
|
@ -182,7 +217,7 @@ public class Session {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gracefully closes the Session: unpublishes all streams and evicts every
|
* Gracefully closes the Session: unpublishes all streams and evicts every
|
||||||
* participant
|
* participant.
|
||||||
*
|
*
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
|
@ -217,15 +252,17 @@ public class Session {
|
||||||
* connections to the Session
|
* connections to the Session
|
||||||
* ({@link io.openvidu.java.client.Session#getActiveConnections()}) and use
|
* ({@link io.openvidu.java.client.Session#getActiveConnections()}) and use
|
||||||
* those values to call
|
* those values to call
|
||||||
* {@link io.openvidu.java.client.Session#forceDisconnect(Connection)} or
|
* {@link io.openvidu.java.client.Session#forceDisconnect(Connection)},
|
||||||
* {@link io.openvidu.java.client.Session#forceUnpublish(Publisher)}. <br>
|
* {@link io.openvidu.java.client.Session#forceUnpublish(Publisher)} or
|
||||||
|
* {@link io.openvidu.java.client.Session#updateConnection(String, TokenOptions)}.<br>
|
||||||
|
* <br>
|
||||||
*
|
*
|
||||||
* To update every Session object owned by OpenVidu object, call
|
* To update all Session objects owned by OpenVidu object at once, call
|
||||||
* {@link io.openvidu.java.client.OpenVidu#fetch()}
|
* {@link io.openvidu.java.client.OpenVidu#fetch()}.
|
||||||
*
|
*
|
||||||
* @return true if the Session status has changed with respect to the server,
|
* @return true if the Session status has changed with respect to the server,
|
||||||
* false if not. This applies to any property or sub-property of the
|
* false if not. This applies to any property or sub-property of the
|
||||||
* object
|
* object.
|
||||||
*
|
*
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
|
@ -263,11 +300,19 @@ public class Session {
|
||||||
* OpenVidu Browser will trigger the proper events on the client-side
|
* OpenVidu Browser will trigger the proper events on the client-side
|
||||||
* (<code>streamDestroyed</code>, <code>connectionDestroyed</code>,
|
* (<code>streamDestroyed</code>, <code>connectionDestroyed</code>,
|
||||||
* <code>sessionDisconnected</code>) with reason set to
|
* <code>sessionDisconnected</code>) with reason set to
|
||||||
* "forceDisconnectByServer" <br>
|
* <code>"forceDisconnectByServer"</code>. <br>
|
||||||
|
* <br>
|
||||||
*
|
*
|
||||||
* You can get <code>connection</code> parameter with
|
* You can get <code>connection</code> parameter with
|
||||||
* {@link io.openvidu.java.client.Session#fetch()} and then
|
* {@link io.openvidu.java.client.Session#fetch()} and then
|
||||||
* {@link io.openvidu.java.client.Session#getActiveConnections()}
|
* {@link io.openvidu.java.client.Session#getActiveConnections()}.<br>
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* This method automatically updates the properties of the local affected
|
||||||
|
* objects. This means that there is no need to call
|
||||||
|
* {@link io.openvidu.java.client.Session#fetch() Session.fetch()} to see the
|
||||||
|
* changes consequence of the execution of this method applied in the local
|
||||||
|
* objects.
|
||||||
*
|
*
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
|
@ -278,15 +323,34 @@ public class Session {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forces the user with Connection <code>connectionId</code> to leave the
|
* Forces the user with Connection <code>connectionId</code> to leave the
|
||||||
* session. OpenVidu Browser will trigger the proper events on the client-side
|
* session, or invalidates the {@link Token} associated with that
|
||||||
|
* <code>connectionId</code> if no user has used it yet. <br>
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* In the first case you can get <code>connectionId</code> parameter from
|
||||||
|
* {@link io.openvidu.java.client.Connection#getConnectionId()
|
||||||
|
* Connection.getConnectionId()}. Connection objects can be listed with
|
||||||
|
* {@link io.openvidu.java.client.Session#getActiveConnections()
|
||||||
|
* Session.getActiveConnections()} (remember to use first
|
||||||
|
* {@link io.openvidu.java.client.Session#fetch() Session.fetch()} to fetch the
|
||||||
|
* current active connections from OpenVidu Server). As a result, OpenVidu
|
||||||
|
* Browser will trigger the proper events on the client-side
|
||||||
* (<code>streamDestroyed</code>, <code>connectionDestroyed</code>,
|
* (<code>streamDestroyed</code>, <code>connectionDestroyed</code>,
|
||||||
* <code>sessionDisconnected</code>) with reason set to
|
* <code>sessionDisconnected</code>) with reason set to
|
||||||
* "forceDisconnectByServer" <br>
|
* <code>"forceDisconnectByServer"</code>. <br>
|
||||||
|
* <br>
|
||||||
*
|
*
|
||||||
* You can get <code>connectionId</code> parameter with
|
* In the second case you can get <code>connectionId</code> parameter from a
|
||||||
* {@link io.openvidu.java.client.Session#fetch()} (use
|
* {@link Token} with {@link Token#getConnectionId()}. As a result, the token
|
||||||
* {@link io.openvidu.java.client.Connection#getConnectionId()} to get the
|
* will be invalidated and no user will be able to connect to the session with
|
||||||
* `connectionId` you want)
|
* it. <br>
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* This method automatically updates the properties of the local affected
|
||||||
|
* objects. This means that there is no need to call
|
||||||
|
* {@link io.openvidu.java.client.Session#fetch() Session.fetch()} to see the
|
||||||
|
* changes consequence of the execution of this method applied in the local
|
||||||
|
* objects.
|
||||||
*
|
*
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
|
@ -336,14 +400,22 @@ public class Session {
|
||||||
/**
|
/**
|
||||||
* Forces some user to unpublish a Stream. OpenVidu Browser will trigger the
|
* Forces some user to unpublish a Stream. OpenVidu Browser will trigger the
|
||||||
* proper events on the client-side (<code>streamDestroyed</code>) with reason
|
* proper events on the client-side (<code>streamDestroyed</code>) with reason
|
||||||
* set to "forceUnpublishByServer".<br>
|
* set to <code>"forceUnpublishByServer"</code>. <br>
|
||||||
|
* <br>
|
||||||
*
|
*
|
||||||
* You can get <code>publisher</code> parameter with
|
* You can get <code>publisher</code> parameter with
|
||||||
* {@link io.openvidu.java.client.Session#getActiveConnections()} and then for
|
* {@link io.openvidu.java.client.Session#getActiveConnections()} and then for
|
||||||
* each Connection you can call
|
* each Connection you can call
|
||||||
* {@link io.openvidu.java.client.Connection#getPublishers()}. Remember to call
|
* {@link io.openvidu.java.client.Connection#getPublishers()}. Remember to call
|
||||||
* {@link io.openvidu.java.client.Session#fetch()} before to fetch the current
|
* {@link io.openvidu.java.client.Session#fetch()} before to fetch the current
|
||||||
* actual properties of the Session from OpenVidu Server
|
* actual properties of the Session from OpenVidu Server.<br>
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* This method automatically updates the properties of the local affected
|
||||||
|
* objects. This means that there is no need to call
|
||||||
|
* {@link io.openvidu.java.client.Session#fetch() Session.fetch()} to see the
|
||||||
|
* changes consequence of the execution of this method applied in the local
|
||||||
|
* objects.
|
||||||
*
|
*
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
|
@ -355,7 +427,8 @@ public class Session {
|
||||||
/**
|
/**
|
||||||
* Forces some user to unpublish a Stream. OpenVidu Browser will trigger the
|
* Forces some user to unpublish a Stream. OpenVidu Browser will trigger the
|
||||||
* proper events on the client-side (<code>streamDestroyed</code>) with reason
|
* proper events on the client-side (<code>streamDestroyed</code>) with reason
|
||||||
* set to "forceUnpublishByServer". <br>
|
* set to <code>"forceUnpublishByServer"</code>. <br>
|
||||||
|
* <br>
|
||||||
*
|
*
|
||||||
* You can get <code>streamId</code> parameter with
|
* You can get <code>streamId</code> parameter with
|
||||||
* {@link io.openvidu.java.client.Session#getActiveConnections()} and then for
|
* {@link io.openvidu.java.client.Session#getActiveConnections()} and then for
|
||||||
|
@ -364,7 +437,14 @@ public class Session {
|
||||||
* {@link io.openvidu.java.client.Publisher#getStreamId()}) will give you the
|
* {@link io.openvidu.java.client.Publisher#getStreamId()}) will give you the
|
||||||
* <code>streamId</code>. Remember to call
|
* <code>streamId</code>. Remember to call
|
||||||
* {@link io.openvidu.java.client.Session#fetch()} before to fetch the current
|
* {@link io.openvidu.java.client.Session#fetch()} before to fetch the current
|
||||||
* actual properties of the Session from OpenVidu Server
|
* actual properties of the Session from OpenVidu Server.<br>
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* This method automatically updates the properties of the local affected
|
||||||
|
* objects. This means that there is no need to call
|
||||||
|
* {@link io.openvidu.java.client.Session#fetch() Session.fetch()} to see the
|
||||||
|
* changes consequence of the execution of this method applied in the local
|
||||||
|
* objects.
|
||||||
*
|
*
|
||||||
* @throws OpenViduJavaClientException
|
* @throws OpenViduJavaClientException
|
||||||
* @throws OpenViduHttpException
|
* @throws OpenViduHttpException
|
||||||
|
@ -401,6 +481,94 @@ public class Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the properties of a Connection. These properties are the ones defined
|
||||||
|
* by the {@link io.openvidu.java.client.TokenOptions} parameter when generating
|
||||||
|
* the token used to create the Connection. These are the properties that can be
|
||||||
|
* updated:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link io.openvidu.java.client.TokenOptions.Builder#role(OpenViduRole)
|
||||||
|
* TokenOptions.Builder.role(OpenViduRole)}</li>
|
||||||
|
* <li>{@link io.openvidu.java.client.TokenOptions.Builder#record(boolean)
|
||||||
|
* TokenOptions.Builder.record(boolean)}</li>
|
||||||
|
* </ul>
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* The <code>connectionId</code> parameter can be obtained from a Connection
|
||||||
|
* object with {@link io.openvidu.java.client.Connection#getConnectionId()
|
||||||
|
* Connection.getConnectionId()}, in which case the updated properties will
|
||||||
|
* modify an active Connection. But <code>connectionId</code> can also be
|
||||||
|
* obtained from a Token with {@link Token#getConnectionId()}, which allows
|
||||||
|
* modifying a still not used token.<br>
|
||||||
|
* <br>
|
||||||
|
*
|
||||||
|
* This method automatically updates the properties of the local affected
|
||||||
|
* objects. This means that there is no need to call
|
||||||
|
* {@link io.openvidu.java.client.Session#fetch() Session.fetch()} to see the
|
||||||
|
* changes consequence of the execution of this method applied in the local
|
||||||
|
* objects.
|
||||||
|
*
|
||||||
|
* @param connectionId The Connection (or a still not used Token) to modify
|
||||||
|
* @param tokenOptions A new TokenOptions object with the updated values to
|
||||||
|
* apply
|
||||||
|
*
|
||||||
|
* @return The updated {@link io.openvidu.java.client.Connection Connection}
|
||||||
|
* object
|
||||||
|
*
|
||||||
|
* @throws OpenViduJavaClientException
|
||||||
|
* @throws OpenViduHttpException
|
||||||
|
*/
|
||||||
|
public Connection updateConnection(String connectionId, TokenOptions tokenOptions)
|
||||||
|
throws OpenViduJavaClientException, OpenViduHttpException {
|
||||||
|
|
||||||
|
HttpPatch request = new HttpPatch(
|
||||||
|
this.openVidu.hostname + OpenVidu.API_SESSIONS + "/" + this.sessionId + "/connection/" + connectionId);
|
||||||
|
|
||||||
|
StringEntity params;
|
||||||
|
try {
|
||||||
|
params = new StringEntity(tokenOptions.toJsonObject(this.sessionId).toString());
|
||||||
|
} catch (UnsupportedEncodingException e1) {
|
||||||
|
throw new OpenViduJavaClientException(e1.getMessage(), e1.getCause());
|
||||||
|
}
|
||||||
|
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
|
||||||
|
request.setEntity(params);
|
||||||
|
|
||||||
|
HttpResponse response;
|
||||||
|
try {
|
||||||
|
response = this.openVidu.httpClient.execute(request);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new OpenViduJavaClientException(e.getMessage(), e.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
|
||||||
|
log.info("Connection {} updated", connectionId);
|
||||||
|
} else if ((statusCode == org.apache.http.HttpStatus.SC_NO_CONTENT)) {
|
||||||
|
log.info("Properties of Connection {} remain the same", connectionId);
|
||||||
|
} else {
|
||||||
|
throw new OpenViduHttpException(statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the actual Connection object with the new options
|
||||||
|
Connection existingConnection = this.activeConnections.get(connectionId);
|
||||||
|
|
||||||
|
if (existingConnection == null) {
|
||||||
|
// The updated Connection is not available in local map
|
||||||
|
Connection newConnection = new Connection(httpResponseToJson(response));
|
||||||
|
this.activeConnections.put(connectionId, newConnection);
|
||||||
|
return newConnection;
|
||||||
|
} else {
|
||||||
|
// The updated Connection was available in local map
|
||||||
|
existingConnection.overrideTokenOptions(tokenOptions);
|
||||||
|
return existingConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
EntityUtils.consumeQuietly(response.getEntity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of active connections to the session. <strong>This value
|
* Returns the list of active connections to the session. <strong>This value
|
||||||
* will remain unchanged since the last time method
|
* will remain unchanged since the last time method
|
||||||
|
@ -408,38 +576,37 @@ public class Session {
|
||||||
* Exceptions to this rule are:
|
* Exceptions to this rule are:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Calling {@link io.openvidu.java.client.Session#forceUnpublish(String)}
|
* <li>Calling {@link io.openvidu.java.client.Session#forceUnpublish(String)}
|
||||||
* updates each affected Connection status</li>
|
* automatically updates each affected local Connection object.</li>
|
||||||
* <li>Calling {@link io.openvidu.java.client.Session#forceDisconnect(String)}
|
* <li>Calling {@link io.openvidu.java.client.Session#forceDisconnect(String)}
|
||||||
* updates each affected Connection status</li>
|
* automatically updates each affected local Connection object.</li>
|
||||||
|
* <li>Calling
|
||||||
|
* {@link io.openvidu.java.client.Session#updateConnection(String, TokenOptions)}
|
||||||
|
* automatically updates the attributes of the affected local Connection
|
||||||
|
* object.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <br>
|
* <br>
|
||||||
* To get the list of active connections with their current actual value, you
|
* To get the list of active connections with their current actual value, you
|
||||||
* must call first {@link io.openvidu.java.client.Session#fetch()} and then
|
* must call first {@link io.openvidu.java.client.Session#fetch()} and then
|
||||||
* {@link io.openvidu.java.client.Session#getActiveConnections()}
|
* {@link io.openvidu.java.client.Session#getActiveConnections()}.
|
||||||
*/
|
*/
|
||||||
public List<Connection> getActiveConnections() {
|
public List<Connection> getActiveConnections() {
|
||||||
return new ArrayList<>(this.activeConnections.values());
|
return new ArrayList<>(this.activeConnections.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the session is being recorded or not
|
* Returns whether the session is being recorded or not.
|
||||||
*/
|
*/
|
||||||
public boolean isBeingRecorded() {
|
public boolean isBeingRecorded() {
|
||||||
return this.recording;
|
return this.recording;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the properties defining the session
|
* Returns the properties defining the session.
|
||||||
*/
|
*/
|
||||||
public SessionProperties getProperties() {
|
public SessionProperties getProperties() {
|
||||||
return this.properties;
|
return this.properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.sessionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasSessionId() {
|
private boolean hasSessionId() {
|
||||||
return (this.sessionId != null && !this.sessionId.isEmpty());
|
return (this.sessionId != null && !this.sessionId.isEmpty());
|
||||||
}
|
}
|
||||||
|
@ -528,35 +695,9 @@ public class Session {
|
||||||
this.properties = builder.build();
|
this.properties = builder.build();
|
||||||
JsonArray jsonArrayConnections = (json.get("connections").getAsJsonObject()).get("content").getAsJsonArray();
|
JsonArray jsonArrayConnections = (json.get("connections").getAsJsonObject()).get("content").getAsJsonArray();
|
||||||
this.activeConnections.clear();
|
this.activeConnections.clear();
|
||||||
jsonArrayConnections.forEach(connection -> {
|
jsonArrayConnections.forEach(connectionJsonElement -> {
|
||||||
JsonObject con = connection.getAsJsonObject();
|
Connection connectionObj = new Connection(connectionJsonElement.getAsJsonObject());
|
||||||
|
this.activeConnections.put(connectionObj.getConnectionId(), connectionObj);
|
||||||
Map<String, Publisher> publishers = new ConcurrentHashMap<>();
|
|
||||||
JsonArray jsonArrayPublishers = con.get("publishers").getAsJsonArray();
|
|
||||||
jsonArrayPublishers.forEach(publisher -> {
|
|
||||||
JsonObject pubJson = publisher.getAsJsonObject();
|
|
||||||
JsonObject mediaOptions = pubJson.get("mediaOptions").getAsJsonObject();
|
|
||||||
Publisher pub = new Publisher(pubJson.get("streamId").getAsString(),
|
|
||||||
pubJson.get("createdAt").getAsLong(), mediaOptions.get("hasAudio").getAsBoolean(),
|
|
||||||
mediaOptions.get("hasVideo").getAsBoolean(), mediaOptions.get("audioActive"),
|
|
||||||
mediaOptions.get("videoActive"), mediaOptions.get("frameRate"), mediaOptions.get("typeOfVideo"),
|
|
||||||
mediaOptions.get("videoDimensions"));
|
|
||||||
publishers.put(pub.getStreamId(), pub);
|
|
||||||
});
|
|
||||||
|
|
||||||
List<String> subscribers = new ArrayList<>();
|
|
||||||
JsonArray jsonArraySubscribers = con.get("subscribers").getAsJsonArray();
|
|
||||||
jsonArraySubscribers.forEach(subscriber -> {
|
|
||||||
subscribers.add((subscriber.getAsJsonObject()).get("streamId").getAsString());
|
|
||||||
});
|
|
||||||
|
|
||||||
Connection c = new Connection(con.get("connectionId").getAsString(), con.get("createdAt").getAsLong(),
|
|
||||||
OpenViduRole.valueOf(con.get("role").getAsString()),
|
|
||||||
(con.has("token") ? con.get("token").getAsString() : null), con.get("location").getAsString(),
|
|
||||||
con.get("platform").getAsString(), con.get("serverData").getAsString(),
|
|
||||||
con.get("clientData").getAsString(), publishers, subscribers);
|
|
||||||
|
|
||||||
this.activeConnections.put(con.get("connectionId").getAsString(), c);
|
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
package io.openvidu.java.client;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
public class Token {
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
private String connectionId;
|
||||||
|
private TokenOptions tokenOptions;
|
||||||
|
|
||||||
|
protected Token(String token, String connectionId, TokenOptions tokenOptions) {
|
||||||
|
this.token = token;
|
||||||
|
this.connectionId = connectionId;
|
||||||
|
this.tokenOptions = tokenOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Token(JsonObject json) {
|
||||||
|
|
||||||
|
this.token = json.get("token").getAsString();
|
||||||
|
this.connectionId = json.get("connectionId").getAsString();
|
||||||
|
|
||||||
|
OpenViduRole role = OpenViduRole.valueOf(json.get("role").getAsString());
|
||||||
|
String data = json.get("data").getAsString();
|
||||||
|
Boolean record = json.get("record").getAsBoolean();
|
||||||
|
|
||||||
|
KurentoOptions kurentoOptions = null;
|
||||||
|
if (json.has("kurentoOptions")) {
|
||||||
|
JsonObject kurentoOptionsJson = json.get("kurentoOptions").getAsJsonObject();
|
||||||
|
|
||||||
|
Integer videoMaxRecvBandwidth = null;
|
||||||
|
Integer videoMinRecvBandwidth = null;
|
||||||
|
Integer videoMaxSendBandwidth = null;
|
||||||
|
Integer videoMinSendBandwidth = null;
|
||||||
|
String[] allowedFilters = null;
|
||||||
|
|
||||||
|
if (kurentoOptionsJson.has("videoMaxRecvBandwidth")) {
|
||||||
|
videoMaxRecvBandwidth = kurentoOptionsJson.get("videoMaxRecvBandwidth").getAsInt();
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("videoMinRecvBandwidth")) {
|
||||||
|
videoMinRecvBandwidth = kurentoOptionsJson.get("videoMinRecvBandwidth").getAsInt();
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("videoMaxSendBandwidth")) {
|
||||||
|
videoMaxSendBandwidth = kurentoOptionsJson.get("videoMaxSendBandwidth").getAsInt();
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("videoMinSendBandwidth")) {
|
||||||
|
videoMinSendBandwidth = kurentoOptionsJson.get("videoMinSendBandwidth").getAsInt();
|
||||||
|
}
|
||||||
|
if (kurentoOptionsJson.has("allowedFilters")) {
|
||||||
|
JsonArray filters = kurentoOptionsJson.get("allowedFilters").getAsJsonArray();
|
||||||
|
allowedFilters = new String[filters.size()];
|
||||||
|
for (int i = 0; i < filters.size(); i++) {
|
||||||
|
allowedFilters[i] = filters.get(i).getAsString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kurentoOptions = new KurentoOptions(videoMaxRecvBandwidth, videoMinRecvBandwidth, videoMaxSendBandwidth,
|
||||||
|
videoMinSendBandwidth, allowedFilters);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tokenOptions = new TokenOptions(role, data, record, kurentoOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the token string value that must be sent to clients. They need to use
|
||||||
|
* it to connect to the session.
|
||||||
|
*/
|
||||||
|
public String getToken() {
|
||||||
|
return this.token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connection identifier that will be associated to the user
|
||||||
|
* consuming this token. This means that the future
|
||||||
|
* {@link io.openvidu.java.client.Connection Connection} object created with
|
||||||
|
* this token will have as <code>connectionId</code> this string. In other
|
||||||
|
* words, method {@link io.openvidu.java.client.Connection#getConnectionId()
|
||||||
|
* Connection.getConnectionId()} will return this same value.
|
||||||
|
*
|
||||||
|
* With <code>connectionId</code> you can call the following methods without
|
||||||
|
* having to fetch and search for the actual
|
||||||
|
* {@link io.openvidu.java.client.Connection Connection} object:
|
||||||
|
* <ul>
|
||||||
|
* <li>Call {@link io.openvidu.java.client.Session#forceDisconnect(String)
|
||||||
|
* Session.forceDisconnect()} to invalidate the token if no client has used it
|
||||||
|
* yet or force the connected client to leave the session if it has.</li>
|
||||||
|
* <li>Call
|
||||||
|
* {@link io.openvidu.java.client.Session#updateConnection(String, TokenOptions)
|
||||||
|
* Session.updateConnection()} to update the
|
||||||
|
* {@link io.openvidu.java.client.Connection Connection} options. And this is
|
||||||
|
* valid for unused tokens, but also for already used tokens, so you can
|
||||||
|
* dynamically change the connection options on the fly.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public String getConnectionId() {
|
||||||
|
return this.connectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the role assigned to this token.
|
||||||
|
*/
|
||||||
|
public OpenViduRole getRole() {
|
||||||
|
return this.tokenOptions.getRole();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the secure (server-side) metadata assigned to this token.
|
||||||
|
*/
|
||||||
|
public String getData() {
|
||||||
|
return this.tokenOptions.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the streams published by the participant owning this token will be
|
||||||
|
* recorded or not. This only affects <a href=
|
||||||
|
* "https://docs.openvidu.io/en/stable/advanced-features/recording#selecting-streams-to-be-recorded"
|
||||||
|
* target="_blank">INDIVIDUAL recording</a>.
|
||||||
|
*/
|
||||||
|
public Boolean record() {
|
||||||
|
return this.tokenOptions.record();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void overrideTokenOptions(TokenOptions tokenOptions) {
|
||||||
|
this.tokenOptions = tokenOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,13 +17,18 @@
|
||||||
|
|
||||||
package io.openvidu.java.client;
|
package io.openvidu.java.client;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link io.openvidu.java.client.Session#generateToken(TokenOptions)}
|
* See {@link io.openvidu.java.client.Session#generateToken(TokenOptions)}
|
||||||
*/
|
*/
|
||||||
public class TokenOptions {
|
public class TokenOptions {
|
||||||
|
|
||||||
private String data;
|
|
||||||
private OpenViduRole role;
|
private OpenViduRole role;
|
||||||
|
private String data;
|
||||||
|
private Boolean record;
|
||||||
private KurentoOptions kurentoOptions;
|
private KurentoOptions kurentoOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,15 +38,24 @@ public class TokenOptions {
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private String data = "";
|
|
||||||
private OpenViduRole role = OpenViduRole.PUBLISHER;
|
private OpenViduRole role = OpenViduRole.PUBLISHER;
|
||||||
|
private String data;
|
||||||
|
private Boolean record = true;
|
||||||
private KurentoOptions kurentoOptions;
|
private KurentoOptions kurentoOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder for {@link io.openvidu.java.client.TokenOptions}
|
* Builder for {@link io.openvidu.java.client.TokenOptions}.
|
||||||
*/
|
*/
|
||||||
public TokenOptions build() {
|
public TokenOptions build() {
|
||||||
return new TokenOptions(this.data, this.role, this.kurentoOptions);
|
return new TokenOptions(this.role, this.data, this.record, this.kurentoOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this method to set the role assigned to this token.
|
||||||
|
*/
|
||||||
|
public Builder role(OpenViduRole role) {
|
||||||
|
this.role = role;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,16 +86,19 @@ public class TokenOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this method to set the role assigned to this token
|
* Call this method to flag the streams published by the participant owning this
|
||||||
|
* token to be recorded or not. This only affects <a href=
|
||||||
|
* "https://docs.openvidu.io/en/stable/advanced-features/recording#selecting-streams-to-be-recorded"
|
||||||
|
* target="_blank">INDIVIDUAL recording</a>. If not set by default will be true.
|
||||||
*/
|
*/
|
||||||
public Builder role(OpenViduRole role) {
|
public Builder record(boolean record) {
|
||||||
this.role = role;
|
this.record = record;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this method to set a {@link io.openvidu.java.client.KurentoOptions}
|
* Call this method to set a {@link io.openvidu.java.client.KurentoOptions}
|
||||||
* object for this token
|
* object for this token.
|
||||||
*/
|
*/
|
||||||
public Builder kurentoOptions(KurentoOptions kurentoOptions) {
|
public Builder kurentoOptions(KurentoOptions kurentoOptions) {
|
||||||
this.kurentoOptions = kurentoOptions;
|
this.kurentoOptions = kurentoOptions;
|
||||||
|
@ -90,31 +107,79 @@ public class TokenOptions {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TokenOptions(String data, OpenViduRole role, KurentoOptions kurentoOptions) {
|
TokenOptions(OpenViduRole role, String data, Boolean record, KurentoOptions kurentoOptions) {
|
||||||
this.data = data;
|
|
||||||
this.role = role;
|
this.role = role;
|
||||||
|
this.data = data;
|
||||||
|
this.record = record;
|
||||||
this.kurentoOptions = kurentoOptions;
|
this.kurentoOptions = kurentoOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the secure (server-side) metadata assigned to this token
|
* Returns the role assigned to this token.
|
||||||
*/
|
|
||||||
public String getData() {
|
|
||||||
return this.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the role assigned to this token
|
|
||||||
*/
|
*/
|
||||||
public OpenViduRole getRole() {
|
public OpenViduRole getRole() {
|
||||||
return this.role;
|
return this.role;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Kurento options assigned to this token
|
* Returns the secure (server-side) metadata assigned to this token.
|
||||||
*/
|
*/
|
||||||
public KurentoOptions getKurentoOptions() {
|
public String getData() {
|
||||||
return this.kurentoOptions;
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the streams published by the participant owning this token will be
|
||||||
|
* recorded or not. This only affects <a href=
|
||||||
|
* "https://docs.openvidu.io/en/stable/advanced-features/recording#selecting-streams-to-be-recorded"
|
||||||
|
* target="_blank">INDIVIDUAL recording</a>.
|
||||||
|
*/
|
||||||
|
public Boolean record() {
|
||||||
|
return this.record;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonObject toJsonObject(String sessionId) {
|
||||||
|
JsonObject json = new JsonObject();
|
||||||
|
json.addProperty("session", sessionId);
|
||||||
|
if (getRole() != null) {
|
||||||
|
json.addProperty("role", getRole().name());
|
||||||
|
} else {
|
||||||
|
json.add("role", JsonNull.INSTANCE);
|
||||||
|
}
|
||||||
|
if (getData() != null) {
|
||||||
|
json.addProperty("data", getData());
|
||||||
|
} else {
|
||||||
|
json.add("data", JsonNull.INSTANCE);
|
||||||
|
}
|
||||||
|
if (record() != null) {
|
||||||
|
json.addProperty("record", record());
|
||||||
|
} else {
|
||||||
|
json.add("record", JsonNull.INSTANCE);
|
||||||
|
}
|
||||||
|
if (this.kurentoOptions != null) {
|
||||||
|
JsonObject kurentoOptions = new JsonObject();
|
||||||
|
if (this.kurentoOptions.getVideoMaxRecvBandwidth() != null) {
|
||||||
|
kurentoOptions.addProperty("videoMaxRecvBandwidth", this.kurentoOptions.getVideoMaxRecvBandwidth());
|
||||||
|
}
|
||||||
|
if (this.kurentoOptions.getVideoMinRecvBandwidth() != null) {
|
||||||
|
kurentoOptions.addProperty("videoMinRecvBandwidth", this.kurentoOptions.getVideoMinRecvBandwidth());
|
||||||
|
}
|
||||||
|
if (this.kurentoOptions.getVideoMaxSendBandwidth() != null) {
|
||||||
|
kurentoOptions.addProperty("videoMaxSendBandwidth", this.kurentoOptions.getVideoMaxSendBandwidth());
|
||||||
|
}
|
||||||
|
if (this.kurentoOptions.getVideoMinSendBandwidth() != null) {
|
||||||
|
kurentoOptions.addProperty("videoMinSendBandwidth", this.kurentoOptions.getVideoMinSendBandwidth());
|
||||||
|
}
|
||||||
|
if (this.kurentoOptions.getAllowedFilters().length > 0) {
|
||||||
|
JsonArray allowedFilters = new JsonArray();
|
||||||
|
for (String filter : this.kurentoOptions.getAllowedFilters()) {
|
||||||
|
allowedFilters.add(filter);
|
||||||
|
}
|
||||||
|
kurentoOptions.add("allowedFilters", allowedFilters);
|
||||||
|
}
|
||||||
|
json.add("kurentoOptions", kurentoOptions);
|
||||||
|
}
|
||||||
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
import { OpenViduRole } from './OpenViduRole';
|
import { OpenViduRole } from './OpenViduRole';
|
||||||
import { Publisher } from './Publisher';
|
import { Publisher } from './Publisher';
|
||||||
|
import { TokenOptions } from './TokenOptions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See [[Session.activeConnections]]
|
* See [[Session.activeConnections]]
|
||||||
|
@ -24,7 +25,8 @@ import { Publisher } from './Publisher';
|
||||||
export class Connection {
|
export class Connection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifier of the connection. You can call [[Session.forceDisconnect]] passing this property as parameter
|
* Identifier of the connection. You can call methods [[Session.forceDisconnect]]
|
||||||
|
* or [[Session.updateConnection]] passing this property as parameter
|
||||||
*/
|
*/
|
||||||
connectionId: string;
|
connectionId: string;
|
||||||
|
|
||||||
|
@ -38,6 +40,16 @@ export class Connection {
|
||||||
*/
|
*/
|
||||||
role: OpenViduRole;
|
role: OpenViduRole;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data associated to the connection on the server-side. This value is set with property [[TokenOptions.data]] when calling [[Session.generateToken]]
|
||||||
|
*/
|
||||||
|
serverData: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to record the streams published by the participant owning this token or not. This only affects [INDIVIDUAL recording](/en/stable/advanced-features/recording#selecting-streams-to-be-recorded)
|
||||||
|
*/
|
||||||
|
record: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token associated to the connection
|
* Token associated to the connection
|
||||||
*/
|
*/
|
||||||
|
@ -54,11 +66,6 @@ export class Connection {
|
||||||
*/
|
*/
|
||||||
platform: string;
|
platform: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Data associated to the connection on the server-side. This value is set with property [[TokenOptions.data]] when calling [[Session.generateToken]]
|
|
||||||
*/
|
|
||||||
serverData: string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data associated to the connection on the client-side. This value is set with second parameter of method
|
* Data associated to the connection on the client-side. This value is set with second parameter of method
|
||||||
* [Session.connect](/en/stable/api/openvidu-browser/classes/session.html#connect) in OpenVidu Browser
|
* [Session.connect](/en/stable/api/openvidu-browser/classes/session.html#connect) in OpenVidu Browser
|
||||||
|
@ -80,18 +87,26 @@ export class Connection {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
constructor(connectionId: string, createdAt: number, role: OpenViduRole, token: string, location: string, platform: string, serverData: string, clientData: string,
|
constructor(json) {
|
||||||
publishers: Publisher[], subscribers: string[]) {
|
if (json.publishers != null) {
|
||||||
this.connectionId = connectionId;
|
json.publishers.forEach(publisher => {
|
||||||
this.createdAt = createdAt;
|
this.publishers.push(new Publisher(publisher));
|
||||||
this.role = role;
|
});
|
||||||
this.token = token;
|
}
|
||||||
this.location = location;
|
if (json.subscribers != null) {
|
||||||
this.platform = platform;
|
json.subscribers.forEach(subscriber => {
|
||||||
this.serverData = serverData;
|
this.subscribers.push(subscriber.streamId);
|
||||||
this.clientData = clientData;
|
});
|
||||||
this.publishers = publishers;
|
}
|
||||||
this.subscribers = subscribers;
|
this.connectionId = json.connectionId;
|
||||||
|
this.createdAt = json.createdAt;
|
||||||
|
this.role = json.role;
|
||||||
|
this.serverData = json.serverData;
|
||||||
|
this.record = json.record;
|
||||||
|
this.token = json.token;
|
||||||
|
this.location = json.location;
|
||||||
|
this.platform = json.platform;
|
||||||
|
this.clientData = json.clientData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,10 +117,11 @@ export class Connection {
|
||||||
this.connectionId === other.connectionId &&
|
this.connectionId === other.connectionId &&
|
||||||
this.createdAt === other.createdAt &&
|
this.createdAt === other.createdAt &&
|
||||||
this.role === other.role &&
|
this.role === other.role &&
|
||||||
|
this.serverData === other.serverData &&
|
||||||
|
this.record === other.record &&
|
||||||
this.token === other.token &&
|
this.token === other.token &&
|
||||||
this.location === other.location &&
|
this.location === other.location &&
|
||||||
this.platform === other.platform &&
|
this.platform === other.platform &&
|
||||||
this.serverData === other.serverData &&
|
|
||||||
this.clientData === other.clientData &&
|
this.clientData === other.clientData &&
|
||||||
this.subscribers.length === other.subscribers.length &&
|
this.subscribers.length === other.subscribers.length &&
|
||||||
this.publishers.length === other.publishers.length);
|
this.publishers.length === other.publishers.length);
|
||||||
|
@ -125,4 +141,17 @@ export class Connection {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
overrideTokenOptions(tokenOptions: TokenOptions): void {
|
||||||
|
if (tokenOptions.role != null) {
|
||||||
|
this.role = tokenOptions.role;
|
||||||
|
}
|
||||||
|
if (tokenOptions.record != null) {
|
||||||
|
this.record = tokenOptions.record
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,16 +15,16 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios, { AxiosError } from 'axios';
|
||||||
import { Connection } from './Connection';
|
import { Connection } from './Connection';
|
||||||
import { MediaMode } from './MediaMode';
|
import { MediaMode } from './MediaMode';
|
||||||
import { OpenVidu } from './OpenVidu';
|
import { OpenVidu } from './OpenVidu';
|
||||||
import { OpenViduRole } from './OpenViduRole';
|
|
||||||
import { Publisher } from './Publisher';
|
import { Publisher } from './Publisher';
|
||||||
import { Recording } from './Recording';
|
import { Recording } from './Recording';
|
||||||
import { RecordingLayout } from './RecordingLayout';
|
import { RecordingLayout } from './RecordingLayout';
|
||||||
import { RecordingMode } from './RecordingMode';
|
import { RecordingMode } from './RecordingMode';
|
||||||
import { SessionProperties } from './SessionProperties';
|
import { SessionProperties } from './SessionProperties';
|
||||||
|
import { Token } from './Token';
|
||||||
import { TokenOptions } from './TokenOptions';
|
import { TokenOptions } from './TokenOptions';
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,8 +49,9 @@ export class Session {
|
||||||
* Array of active connections to the session. This property always initialize as an empty array and
|
* Array of active connections to the session. This property always initialize as an empty array and
|
||||||
* **will remain unchanged since the last time method [[Session.fetch]] was called**. Exceptions to this rule are:
|
* **will remain unchanged since the last time method [[Session.fetch]] was called**. Exceptions to this rule are:
|
||||||
*
|
*
|
||||||
* - Calling [[Session.forceUnpublish]] also automatically updates each affected Connection status
|
* - Calling [[Session.forceUnpublish]] automatically updates each affected local Connection object.
|
||||||
* - Calling [[Session.forceDisconnect]] automatically updates each affected Connection status
|
* - Calling [[Session.forceDisconnect]] automatically updates each affected local Connection object.
|
||||||
|
* - Calling [[Session.updateConnection]] automatically updates the attributes of the affected local Connection object.
|
||||||
*
|
*
|
||||||
* To get the array of active connections with their current actual value, you must call [[Session.fetch]] before consulting
|
* To get the array of active connections with their current actual value, you must call [[Session.fetch]] before consulting
|
||||||
* property [[activeConnections]]
|
* property [[activeConnections]]
|
||||||
|
@ -93,12 +94,36 @@ export class Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a new token associated to Session object
|
* @deprecated Use [[Session.createToken]] instead to get a [[Token]] object.
|
||||||
*
|
*
|
||||||
* @returns A Promise that is resolved to the _token_ if success and rejected with an Error object if not
|
* @returns A Promise that is resolved to the generated _token_ string if success and rejected with an Error object if not
|
||||||
*/
|
*/
|
||||||
public generateToken(tokenOptions?: TokenOptions): Promise<string> {
|
public generateToken(tokenOptions?: TokenOptions): Promise<string> {
|
||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
this.createToken(tokenOptions).then(token => resolve(token.token)).catch(error => reject(error));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a new token object associated to Session object configured with
|
||||||
|
* `tokenOptions`. The token string value to send to the client side
|
||||||
|
* is available at [[Token.token]] property.
|
||||||
|
*
|
||||||
|
* Property [[Token.connectionId]] provides the connection identifier that will be given
|
||||||
|
* to the user consuming the token. With `connectionId` you can call
|
||||||
|
* the following methods without having to fetch and search for the actual
|
||||||
|
* [[Connection]] object:
|
||||||
|
*
|
||||||
|
* - Call [[Session.forceDisconnect]] to invalidate the token if no client has used it
|
||||||
|
* yet or force the connected client to leave the session if it has.
|
||||||
|
* - Call [[Session.updateConnection]] to update the [[Connection]] options. And this is
|
||||||
|
* valid for unused tokens, but also for already used tokens, so you can
|
||||||
|
* dynamically change the user connection options on the fly.
|
||||||
|
*
|
||||||
|
* @returns A Promise that is resolved to the generated [[Token]] object if success and rejected with an Error object if not
|
||||||
|
*/
|
||||||
|
public createToken(tokenOptions?: TokenOptions): Promise<Token> {
|
||||||
|
return new Promise<Token>((resolve, reject) => {
|
||||||
|
|
||||||
const data = JSON.stringify({
|
const data = JSON.stringify({
|
||||||
session: this.sessionId,
|
session: this.sessionId,
|
||||||
|
@ -120,26 +145,13 @@ export class Session {
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
// SUCCESS response from openvidu-server. Resolve token
|
// SUCCESS response from openvidu-server. Resolve token
|
||||||
resolve(res.data.id);
|
resolve(new Token(res.data));
|
||||||
} else {
|
} else {
|
||||||
// ERROR response from openvidu-server. Resolve HTTP status
|
// ERROR response from openvidu-server. Resolve HTTP status
|
||||||
reject(new Error(res.status.toString()));
|
reject(new Error(res.status.toString()));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if (error.response) {
|
this.handleError(error, reject);
|
||||||
// The request was made and the server responded with a status code (not 2xx)
|
|
||||||
reject(new Error(error.response.status.toString()));
|
|
||||||
} else if (error.request) {
|
|
||||||
// The request was made but no response was received
|
|
||||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
||||||
// http.ClientRequest in node.js
|
|
||||||
console.error(error.request);
|
|
||||||
reject(new Error(error.request));
|
|
||||||
} else {
|
|
||||||
// Something happened in setting up the request that triggered an Error
|
|
||||||
console.error('Error', error.message);
|
|
||||||
reject(new Error(error.message));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -171,29 +183,17 @@ export class Session {
|
||||||
reject(new Error(res.status.toString()));
|
reject(new Error(res.status.toString()));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if (error.response) {
|
this.handleError(error, reject);
|
||||||
// The request was made and the server responded with a status code (not 2xx)
|
|
||||||
reject(new Error(error.response.status.toString()));
|
|
||||||
} else if (error.request) {
|
|
||||||
// The request was made but no response was received
|
|
||||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
||||||
// http.ClientRequest in node.js
|
|
||||||
console.error(error.request);
|
|
||||||
reject(new Error(error.request));
|
|
||||||
} else {
|
|
||||||
// Something happened in setting up the request that triggered an Error
|
|
||||||
console.error('Error', error.message);
|
|
||||||
reject(new Error(error.message));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates every property of the Session with the current status it has in OpenVidu Server. This is especially useful for accessing the list of active
|
* Updates every property of the Session with the current status it has in OpenVidu Server. This is especially useful for accessing the list of active
|
||||||
* connections of the Session ([[Session.activeConnections]]) and use those values to call [[Session.forceDisconnect]] or [[Session.forceUnpublish]].
|
* connections of the Session ([[Session.activeConnections]]) and use those values to call [[Session.forceDisconnect]], [[Session.forceUnpublish]] or
|
||||||
|
* [[Session.updateConnection]].
|
||||||
*
|
*
|
||||||
* To update every Session object owned by OpenVidu object, call [[OpenVidu.fetch]]
|
* To update all Session objects owned by OpenVidu object at once, call [[OpenVidu.fetch]]
|
||||||
*
|
*
|
||||||
* @returns A promise resolved to true if the Session status has changed with respect to the server, or to false if not.
|
* @returns A promise resolved to true if the Session status has changed with respect to the server, or to false if not.
|
||||||
* This applies to any property or sub-property of the Session object
|
* This applies to any property or sub-property of the Session object
|
||||||
|
@ -223,30 +223,26 @@ export class Session {
|
||||||
reject(new Error(res.status.toString()));
|
reject(new Error(res.status.toString()));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if (error.response) {
|
this.handleError(error, reject);
|
||||||
// The request was made and the server responded with a status code (not 2xx)
|
|
||||||
reject(new Error(error.response.status.toString()));
|
|
||||||
} else if (error.request) {
|
|
||||||
// The request was made but no response was received
|
|
||||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
||||||
// http.ClientRequest in node.js
|
|
||||||
console.error(error.request);
|
|
||||||
reject(new Error(error.request));
|
|
||||||
} else {
|
|
||||||
// Something happened in setting up the request that triggered an Error
|
|
||||||
console.error('Error', error.message);
|
|
||||||
reject(new Error(error.message));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forces the user with Connection `connectionId` to leave the session. OpenVidu Browser will trigger the proper events on the client-side
|
* Forces the user with Connection `connectionId` to leave the session, or invalidates the [[Token]] associated with that
|
||||||
* (`streamDestroyed`, `connectionDestroyed`, `sessionDisconnected`) with reason set to `"forceDisconnectByServer"`
|
* `connectionId` if no user has used it yet.
|
||||||
*
|
*
|
||||||
* You can get `connection` parameter from [[Session.activeConnections]] array ([[Connection.connectionId]] for getting each `connectionId` property).
|
* In the first case you can get `connection` parameter from [[Session.activeConnections]] array (remember to call [[Session.fetch]] before
|
||||||
* Remember to call [[Session.fetch]] before to fetch the current actual properties of the Session from OpenVidu Server
|
* to fetch the current actual properties of the Session from OpenVidu Server). As a result, OpenVidu Browser will trigger the proper
|
||||||
|
* events on the client-side (`streamDestroyed`, `connectionDestroyed`, `sessionDisconnected`) with reason set to `"forceDisconnectByServer"`.
|
||||||
|
*
|
||||||
|
* In the second case you can get `connectionId` parameter with [[Token.connectionId]]. As a result, the token will be invalidated
|
||||||
|
* and no user will be able to connect to the session with it.
|
||||||
|
*
|
||||||
|
* This method automatically updates the properties of the local affected objects. This means that there is no need to call
|
||||||
|
* [[Session.fetch]] to see the changes consequence of the execution of this method applied in the local objects.
|
||||||
|
*
|
||||||
|
* @param connection The Connection object to disconnect from the session, or its `connectionId` property
|
||||||
*
|
*
|
||||||
* @returns A Promise that is resolved if the user was successfully disconnected and rejected with an Error object if not
|
* @returns A Promise that is resolved if the user was successfully disconnected and rejected with an Error object if not
|
||||||
*/
|
*/
|
||||||
|
@ -302,20 +298,7 @@ export class Session {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
if (error.response) {
|
this.handleError(error, reject);
|
||||||
// The request was made and the server responded with a status code (not 2xx)
|
|
||||||
reject(new Error(error.response.status.toString()));
|
|
||||||
} else if (error.request) {
|
|
||||||
// The request was made but no response was received
|
|
||||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
||||||
// http.ClientRequest in node.js
|
|
||||||
console.error(error.request);
|
|
||||||
reject(new Error(error.request));
|
|
||||||
} else {
|
|
||||||
// Something happened in setting up the request that triggered an Error
|
|
||||||
console.error('Error', error.message);
|
|
||||||
reject(new Error(error.message));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -327,6 +310,9 @@ export class Session {
|
||||||
* You can get `publisher` parameter from [[Connection.publishers]] array ([[Publisher.streamId]] for getting each `streamId` property).
|
* You can get `publisher` parameter from [[Connection.publishers]] array ([[Publisher.streamId]] for getting each `streamId` property).
|
||||||
* Remember to call [[Session.fetch]] before to fetch the current actual properties of the Session from OpenVidu Server
|
* Remember to call [[Session.fetch]] before to fetch the current actual properties of the Session from OpenVidu Server
|
||||||
*
|
*
|
||||||
|
* This method automatically updates the properties of the local affected objects. This means that there is no need to call
|
||||||
|
* [[Session.fetch]] to see the changes consequence of the execution of this method applied in the local objects.
|
||||||
|
*
|
||||||
* @returns A Promise that is resolved if the stream was successfully unpublished and rejected with an Error object if not
|
* @returns A Promise that is resolved if the stream was successfully unpublished and rejected with an Error object if not
|
||||||
*/
|
*/
|
||||||
public forceUnpublish(publisher: string | Publisher): Promise<any> {
|
public forceUnpublish(publisher: string | Publisher): Promise<any> {
|
||||||
|
@ -367,20 +353,70 @@ export class Session {
|
||||||
reject(new Error(res.status.toString()));
|
reject(new Error(res.status.toString()));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if (error.response) {
|
this.handleError(error, reject);
|
||||||
// The request was made and the server responded with a status code (not 2xx)
|
});
|
||||||
reject(new Error(error.response.status.toString()));
|
});
|
||||||
} else if (error.request) {
|
|
||||||
// The request was made but no response was received
|
|
||||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
|
||||||
// http.ClientRequest in node.js
|
|
||||||
console.error(error.request);
|
|
||||||
reject(new Error(error.request));
|
|
||||||
} else {
|
|
||||||
// Something happened in setting up the request that triggered an Error
|
|
||||||
console.error('Error', error.message);
|
|
||||||
reject(new Error(error.message));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the properties of a Connection. These properties are the ones defined
|
||||||
|
* by the [[TokenOptions]] parameter when generating the token used to create the Connection.
|
||||||
|
* These are the properties that can be updated:
|
||||||
|
*
|
||||||
|
* - [[TokenOptions.role]]
|
||||||
|
* - [[TokenOptions.record]]
|
||||||
|
*
|
||||||
|
* The `connectionId` parameter can be obtained from a Connection object with
|
||||||
|
* [[Connection.connectionId]], in which case the updated properties will
|
||||||
|
* modify an active Connection. But `connectionId` can also be obtained from a
|
||||||
|
* Token with [[Token.connectionId]], which allows modifying a still not used token.
|
||||||
|
*
|
||||||
|
* This method automatically updates the properties of the local affected objects. This means that there is no need to call
|
||||||
|
* [[Session.fetch]] to see the changes consequence of the execution of this method applied in the local objects.
|
||||||
|
*
|
||||||
|
* @param connectionId The [[Connection.connectionId]] property of the Connection object to modify,
|
||||||
|
* or the [[Token.connectionId]] property of a still not used token to modify
|
||||||
|
* @param tokenOptions A new [[TokenOptions]] object with the updated values to apply
|
||||||
|
*
|
||||||
|
* @returns A Promise that is resolved to the updated [[Connection]] object if the operation was
|
||||||
|
* successful and rejected with an Error object if not
|
||||||
|
*/
|
||||||
|
public updateConnection(connectionId: string, tokenOptions: TokenOptions): Promise<Connection> {
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
axios.patch(
|
||||||
|
this.ov.host + OpenVidu.API_SESSIONS + "/" + this.sessionId + "/connection/" + connectionId,
|
||||||
|
tokenOptions,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Authorization': this.ov.basicAuth,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
console.log('Connection ' + connectionId + ' updated');
|
||||||
|
} else if (res.status === 204) {
|
||||||
|
console.log('Properties of Connection ' + connectionId + ' remain the same');
|
||||||
|
} else {
|
||||||
|
// ERROR response from openvidu-server. Resolve HTTP status
|
||||||
|
reject(new Error(res.status.toString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Update the actual Connection object with the new options
|
||||||
|
const existingConnection: Connection = this.activeConnections.find(con => con.connectionId === connectionId);
|
||||||
|
if (!existingConnection) {
|
||||||
|
// The updated Connection is not available in local map
|
||||||
|
const newConnection: Connection = new Connection(res.data);
|
||||||
|
this.activeConnections.push(newConnection);
|
||||||
|
resolve(newConnection);
|
||||||
|
} else {
|
||||||
|
// The updated Connection was available in local map
|
||||||
|
existingConnection.overrideTokenOptions(tokenOptions);
|
||||||
|
resolve(existingConnection);
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.handleError(error, reject);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -478,28 +514,8 @@ export class Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.activeConnections = [];
|
this.activeConnections = [];
|
||||||
json.connections.content.forEach(connection => {
|
json.connections.content.forEach(jsonConnection => this.activeConnections.push(new Connection(jsonConnection)));
|
||||||
const publishers: Publisher[] = [];
|
|
||||||
connection.publishers.forEach(publisher => {
|
|
||||||
publishers.push(new Publisher(publisher));
|
|
||||||
});
|
|
||||||
const subscribers: string[] = [];
|
|
||||||
connection.subscribers.forEach(subscriber => {
|
|
||||||
subscribers.push(subscriber.streamId);
|
|
||||||
});
|
|
||||||
this.activeConnections.push(
|
|
||||||
new Connection(
|
|
||||||
connection.connectionId,
|
|
||||||
connection.createdAt,
|
|
||||||
connection.role,
|
|
||||||
connection.token,
|
|
||||||
connection.location,
|
|
||||||
connection.platform,
|
|
||||||
connection.serverData,
|
|
||||||
connection.clientData,
|
|
||||||
publishers,
|
|
||||||
subscribers));
|
|
||||||
});
|
|
||||||
// Order connections by time of creation
|
// Order connections by time of creation
|
||||||
this.activeConnections.sort((c1, c2) => (c1.createdAt > c2.createdAt) ? 1 : ((c2.createdAt > c1.createdAt) ? -1 : 0));
|
this.activeConnections.sort((c1, c2) => (c1.createdAt > c2.createdAt) ? 1 : ((c2.createdAt > c1.createdAt) ? -1 : 0));
|
||||||
return this;
|
return this;
|
||||||
|
@ -539,4 +555,24 @@ export class Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
private handleError(error: AxiosError, reject: (reason?: any) => void) {
|
||||||
|
if (error.response) {
|
||||||
|
// The request was made and the server responded with a status code (not 2xx)
|
||||||
|
reject(new Error(error.response.status.toString()));
|
||||||
|
} else if (error.request) {
|
||||||
|
// The request was made but no response was received
|
||||||
|
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
||||||
|
// http.ClientRequest in node.js
|
||||||
|
console.error(error.request);
|
||||||
|
reject(new Error(error.request));
|
||||||
|
} else {
|
||||||
|
// Something happened in setting up the request that triggered an Error
|
||||||
|
console.error('Error', error.message);
|
||||||
|
reject(new Error(error.message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2017-2020 OpenVidu (https://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { TokenOptions } from './TokenOptions';
|
||||||
|
|
||||||
|
export class Token {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The token string value that must be sent to clients. They need to use it to connect to the session.
|
||||||
|
*/
|
||||||
|
token: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection identifier that will be associated to the user
|
||||||
|
* consuming this token. This means that the future [[Connection]] object created with
|
||||||
|
* this token will have as [[Connection.connectionId]] this same value.
|
||||||
|
*
|
||||||
|
* With `connectionId` you can call the following methods without
|
||||||
|
* having to fetch and search for the actual [[Connection]] object:
|
||||||
|
*
|
||||||
|
* - Call [[Session.forceDisconnect]] to invalidate the token if no client has used it
|
||||||
|
* yet or force the connected client to leave the session if it has.
|
||||||
|
* - Call [[Session.updateConnection]] to update the [[Connection]] options. And this is
|
||||||
|
* valid for unused tokens, but also for already used tokens, so you can
|
||||||
|
* dynamically change the connection options on the fly.
|
||||||
|
*/
|
||||||
|
connectionId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The [[TokenOptions]] assigned to this token.
|
||||||
|
*/
|
||||||
|
tokenOptions: TokenOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
constructor(json) {
|
||||||
|
this.token = json.token;
|
||||||
|
this.connectionId = json.connectionId;
|
||||||
|
let possibleKurentoOptions;
|
||||||
|
if (!!json.kurentoOptions) {
|
||||||
|
possibleKurentoOptions = {};
|
||||||
|
if (json.kurentoOptions.videoMaxRecvBandwidth != null) {
|
||||||
|
possibleKurentoOptions['videoMaxRecvBandwidth'] = json.kurentoOptions.videoMaxRecvBandwidth;
|
||||||
|
}
|
||||||
|
if (json.kurentoOptions.videoMinRecvBandwidth != null) {
|
||||||
|
possibleKurentoOptions['videoMinRecvBandwidth'] = json.kurentoOptions.videoMinRecvBandwidth;
|
||||||
|
}
|
||||||
|
if (json.kurentoOptions.videoMaxSendBandwidth != null) {
|
||||||
|
possibleKurentoOptions['videoMaxSendBandwidth'] = json.kurentoOptions.videoMaxSendBandwidth;
|
||||||
|
}
|
||||||
|
if (json.kurentoOptions.videoMinSendBandwidth != null) {
|
||||||
|
possibleKurentoOptions['videoMinSendBandwidth'] = json.kurentoOptions.videoMinSendBandwidth;
|
||||||
|
}
|
||||||
|
if (json.kurentoOptions.allowedFilters != null) {
|
||||||
|
possibleKurentoOptions['allowedFilters'] = json.kurentoOptions.allowedFilters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tokenOptions = {
|
||||||
|
role: json.role,
|
||||||
|
data: json.data,
|
||||||
|
record: json.record,
|
||||||
|
kurentoOptions: possibleKurentoOptions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -44,7 +44,6 @@ export interface TokenOptions {
|
||||||
*/
|
*/
|
||||||
record?: boolean;
|
record?: boolean;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **WARNING**: experimental option. This interface may change in the near future
|
* **WARNING**: experimental option. This interface may change in the near future
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,6 +3,7 @@ export * from './OpenViduRole';
|
||||||
export * from './Session';
|
export * from './Session';
|
||||||
export * from './SessionProperties';
|
export * from './SessionProperties';
|
||||||
export * from './TokenOptions';
|
export * from './TokenOptions';
|
||||||
|
export * from './Token';
|
||||||
export * from './MediaMode';
|
export * from './MediaMode';
|
||||||
export * from './RecordingLayout';
|
export * from './RecordingLayout';
|
||||||
export * from './RecordingMode';
|
export * from './RecordingMode';
|
||||||
|
|
Loading…
Reference in New Issue