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.List;
|
||||
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()}
|
||||
|
@ -28,35 +32,52 @@ public class Connection {
|
|||
|
||||
private String connectionId;
|
||||
private long createdAt;
|
||||
private OpenViduRole role;
|
||||
private String token;
|
||||
private String location;
|
||||
private String platform;
|
||||
private String serverData;
|
||||
private String clientData;
|
||||
private Token token;
|
||||
|
||||
protected Map<String, Publisher> publishers;
|
||||
protected List<String> subscribers;
|
||||
protected Map<String, Publisher> publishers = new ConcurrentHashMap<>();
|
||||
protected List<String> subscribers = new ArrayList<>();
|
||||
|
||||
protected Connection(String connectionId, long createdAt, OpenViduRole role, String token, String location,
|
||||
String platform, String serverData, String clientData, Map<String, Publisher> publishers,
|
||||
List<String> subscribers) {
|
||||
this.connectionId = connectionId;
|
||||
this.createdAt = createdAt;
|
||||
this.role = role;
|
||||
this.token = token;
|
||||
this.location = location;
|
||||
this.platform = platform;
|
||||
this.serverData = serverData;
|
||||
this.clientData = clientData;
|
||||
this.publishers = publishers;
|
||||
this.subscribers = subscribers;
|
||||
protected Connection(JsonObject json) {
|
||||
JsonArray jsonArrayPublishers = json.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"));
|
||||
this.publishers.put(pub.getStreamId(), pub);
|
||||
});
|
||||
|
||||
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
|
||||
* {@link io.openvidu.java.client.Session#forceDisconnect(String)} passing this
|
||||
* property as parameter
|
||||
* Returns the identifier of the connection. You can call methods
|
||||
* {@link io.openvidu.java.client.Session#forceDisconnect(String)} or
|
||||
* {@link io.openvidu.java.client.Session#updateConnection(String, TokenOptions)}
|
||||
* passing this property as parameter
|
||||
*/
|
||||
public String getConnectionId() {
|
||||
return connectionId;
|
||||
|
@ -74,21 +95,41 @@ public class Connection {
|
|||
* Returns the role of the connection
|
||||
*/
|
||||
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() {
|
||||
return token;
|
||||
return this.token.getToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* <a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank" style="display:
|
||||
* inline-block; background-color: rgb(0, 136, 170); color: white; font-weight:
|
||||
* bold; padding: 0px 5px; margin-right: 5px; border-radius: 3px; font-size:
|
||||
* 13px; line-height:21px; font-family: Montserrat, sans-serif">PRO</a>
|
||||
* <a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank"
|
||||
* style="display: inline-block; background-color: rgb(0, 136, 170); color:
|
||||
* white; font-weight: bold; padding: 0px 5px; margin-right: 5px; border-radius:
|
||||
* 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:
|
||||
* <code>"CITY, COUNTRY"</code> (<code>"unknown"</code> if it wasn't possible to
|
||||
|
@ -106,20 +147,11 @@ public class Connection {
|
|||
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
|
||||
* is set with second parameter of method
|
||||
* <a href="https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html#connect" target
|
||||
* ="_blank">Session.connect</a> in OpenVidu Browser
|
||||
* is set with second parameter of method <a href=
|
||||
* "https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/session.html#connect"
|
||||
* target ="_blank">Session.connect</a> in OpenVidu Browser
|
||||
*/
|
||||
public String getClientData() {
|
||||
return clientData;
|
||||
|
@ -147,6 +179,16 @@ public class Connection {
|
|||
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) {
|
||||
this.subscribers = subscribers;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.http.HttpHeaders;
|
|||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
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.entity.StringEntity;
|
||||
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
|
||||
*/
|
||||
|
@ -80,78 +81,112 @@ public class Session {
|
|||
|
||||
/**
|
||||
* 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() {
|
||||
return this.createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new token associated to Session object with default values for
|
||||
* {@link io.openvidu.java.client.TokenOptions}. This always translates into a
|
||||
* new request to OpenVidu Server
|
||||
* @deprecated Use {@link Session#createToken() Session.createToken()} instead
|
||||
* to get a {@link io.openvidu.java.client.Token} object.
|
||||
*
|
||||
* @return The generated token
|
||||
* @return The generated token String
|
||||
*
|
||||
* @throws OpenViduJavaClientException
|
||||
* @throws OpenViduHttpException
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* <code>tokenOptions</code>. This always translates into a new request to
|
||||
* OpenVidu Server
|
||||
* @deprecated Use
|
||||
* {@link Session#createToken(io.openvidu.java.client.TokenOptions)
|
||||
* 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 OpenViduHttpException
|
||||
*/
|
||||
@Deprecated
|
||||
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()) {
|
||||
this.getSessionId();
|
||||
}
|
||||
|
||||
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;
|
||||
try {
|
||||
params = new StringEntity(json.toString());
|
||||
params = new StringEntity(tokenOptions.toJsonObject(sessionId).toString());
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
throw new OpenViduJavaClientException(e1.getMessage(), e1.getCause());
|
||||
}
|
||||
|
@ -169,8 +204,8 @@ public class Session {
|
|||
try {
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if ((statusCode == org.apache.http.HttpStatus.SC_OK)) {
|
||||
String token = httpResponseToJson(response).get("id").getAsString();
|
||||
log.info("Returning a TOKEN: {}", token);
|
||||
Token token = new Token(httpResponseToJson(response));
|
||||
log.info("Returning a TOKEN: {}", token.getToken());
|
||||
return token;
|
||||
} else {
|
||||
throw new OpenViduHttpException(statusCode);
|
||||
|
@ -182,7 +217,7 @@ public class Session {
|
|||
|
||||
/**
|
||||
* Gracefully closes the Session: unpublishes all streams and evicts every
|
||||
* participant
|
||||
* participant.
|
||||
*
|
||||
* @throws OpenViduJavaClientException
|
||||
* @throws OpenViduHttpException
|
||||
|
@ -217,15 +252,17 @@ public class Session {
|
|||
* connections to the Session
|
||||
* ({@link io.openvidu.java.client.Session#getActiveConnections()}) and use
|
||||
* those values to call
|
||||
* {@link io.openvidu.java.client.Session#forceDisconnect(Connection)} or
|
||||
* {@link io.openvidu.java.client.Session#forceUnpublish(Publisher)}. <br>
|
||||
* {@link io.openvidu.java.client.Session#forceDisconnect(Connection)},
|
||||
* {@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
|
||||
* {@link io.openvidu.java.client.OpenVidu#fetch()}
|
||||
* To update all Session objects owned by OpenVidu object at once, call
|
||||
* {@link io.openvidu.java.client.OpenVidu#fetch()}.
|
||||
*
|
||||
* @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
|
||||
* object
|
||||
* object.
|
||||
*
|
||||
* @throws OpenViduHttpException
|
||||
* @throws OpenViduJavaClientException
|
||||
|
@ -263,11 +300,19 @@ public class Session {
|
|||
* OpenVidu Browser will trigger the proper events on the client-side
|
||||
* (<code>streamDestroyed</code>, <code>connectionDestroyed</code>,
|
||||
* <code>sessionDisconnected</code>) with reason set to
|
||||
* "forceDisconnectByServer" <br>
|
||||
* <code>"forceDisconnectByServer"</code>. <br>
|
||||
* <br>
|
||||
*
|
||||
* You can get <code>connection</code> parameter with
|
||||
* {@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 OpenViduHttpException
|
||||
|
@ -278,15 +323,34 @@ public class Session {
|
|||
|
||||
/**
|
||||
* 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>sessionDisconnected</code>) with reason set to
|
||||
* "forceDisconnectByServer" <br>
|
||||
* <code>"forceDisconnectByServer"</code>. <br>
|
||||
* <br>
|
||||
*
|
||||
* You can get <code>connectionId</code> parameter with
|
||||
* {@link io.openvidu.java.client.Session#fetch()} (use
|
||||
* {@link io.openvidu.java.client.Connection#getConnectionId()} to get the
|
||||
* `connectionId` you want)
|
||||
* In the second case you can get <code>connectionId</code> parameter from a
|
||||
* {@link Token} with {@link Token#getConnectionId()}. As a result, the token
|
||||
* will be invalidated and no user will be able to connect to the session with
|
||||
* 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 OpenViduHttpException
|
||||
|
@ -336,14 +400,22 @@ public class Session {
|
|||
/**
|
||||
* Forces some user to unpublish a Stream. OpenVidu Browser will trigger the
|
||||
* 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
|
||||
* {@link io.openvidu.java.client.Session#getActiveConnections()} and then for
|
||||
* each Connection you can call
|
||||
* {@link io.openvidu.java.client.Connection#getPublishers()}. Remember to call
|
||||
* {@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 OpenViduHttpException
|
||||
|
@ -355,7 +427,8 @@ public class Session {
|
|||
/**
|
||||
* Forces some user to unpublish a Stream. OpenVidu Browser will trigger the
|
||||
* 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
|
||||
* {@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
|
||||
* <code>streamId</code>. Remember to call
|
||||
* {@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 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
|
||||
* will remain unchanged since the last time method
|
||||
|
@ -408,38 +576,37 @@ public class Session {
|
|||
* Exceptions to this rule are:
|
||||
* <ul>
|
||||
* <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)}
|
||||
* 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>
|
||||
* <br>
|
||||
* 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
|
||||
* {@link io.openvidu.java.client.Session#getActiveConnections()}
|
||||
* {@link io.openvidu.java.client.Session#getActiveConnections()}.
|
||||
*/
|
||||
public List<Connection> getActiveConnections() {
|
||||
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() {
|
||||
return this.recording;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the properties defining the session
|
||||
* Returns the properties defining the session.
|
||||
*/
|
||||
public SessionProperties getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.sessionId;
|
||||
}
|
||||
|
||||
private boolean hasSessionId() {
|
||||
return (this.sessionId != null && !this.sessionId.isEmpty());
|
||||
}
|
||||
|
@ -528,35 +695,9 @@ public class Session {
|
|||
this.properties = builder.build();
|
||||
JsonArray jsonArrayConnections = (json.get("connections").getAsJsonObject()).get("content").getAsJsonArray();
|
||||
this.activeConnections.clear();
|
||||
jsonArrayConnections.forEach(connection -> {
|
||||
JsonObject con = connection.getAsJsonObject();
|
||||
|
||||
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);
|
||||
jsonArrayConnections.forEach(connectionJsonElement -> {
|
||||
Connection connectionObj = new Connection(connectionJsonElement.getAsJsonObject());
|
||||
this.activeConnections.put(connectionObj.getConnectionId(), connectionObj);
|
||||
});
|
||||
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;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* See {@link io.openvidu.java.client.Session#generateToken(TokenOptions)}
|
||||
*/
|
||||
public class TokenOptions {
|
||||
|
||||
private String data;
|
||||
private OpenViduRole role;
|
||||
private String data;
|
||||
private Boolean record;
|
||||
private KurentoOptions kurentoOptions;
|
||||
|
||||
/**
|
||||
|
@ -33,15 +38,24 @@ public class TokenOptions {
|
|||
*/
|
||||
public static class Builder {
|
||||
|
||||
private String data = "";
|
||||
private OpenViduRole role = OpenViduRole.PUBLISHER;
|
||||
private String data;
|
||||
private Boolean record = true;
|
||||
private KurentoOptions kurentoOptions;
|
||||
|
||||
/**
|
||||
* Builder for {@link io.openvidu.java.client.TokenOptions}
|
||||
* Builder for {@link io.openvidu.java.client.TokenOptions}.
|
||||
*/
|
||||
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) {
|
||||
this.role = role;
|
||||
public Builder record(boolean record) {
|
||||
this.record = record;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
this.kurentoOptions = kurentoOptions;
|
||||
|
@ -90,31 +107,79 @@ public class TokenOptions {
|
|||
|
||||
}
|
||||
|
||||
private TokenOptions(String data, OpenViduRole role, KurentoOptions kurentoOptions) {
|
||||
this.data = data;
|
||||
TokenOptions(OpenViduRole role, String data, Boolean record, KurentoOptions kurentoOptions) {
|
||||
this.role = role;
|
||||
this.data = data;
|
||||
this.record = record;
|
||||
this.kurentoOptions = kurentoOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the secure (server-side) metadata assigned to this token
|
||||
*/
|
||||
public String getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the role assigned to this token
|
||||
* Returns the role assigned to this token.
|
||||
*/
|
||||
public OpenViduRole getRole() {
|
||||
return this.role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Kurento options assigned to this token
|
||||
* Returns the secure (server-side) metadata assigned to this token.
|
||||
*/
|
||||
public KurentoOptions getKurentoOptions() {
|
||||
return this.kurentoOptions;
|
||||
public String getData() {
|
||||
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 { Publisher } from './Publisher';
|
||||
import { TokenOptions } from './TokenOptions';
|
||||
|
||||
/**
|
||||
* See [[Session.activeConnections]]
|
||||
|
@ -24,7 +25,8 @@ import { Publisher } from './Publisher';
|
|||
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;
|
||||
|
||||
|
@ -38,6 +40,16 @@ export class Connection {
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -54,11 +66,6 @@ export class Connection {
|
|||
*/
|
||||
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
|
||||
* [Session.connect](/en/stable/api/openvidu-browser/classes/session.html#connect) in OpenVidu Browser
|
||||
|
@ -80,18 +87,26 @@ export class Connection {
|
|||
/**
|
||||
* @hidden
|
||||
*/
|
||||
constructor(connectionId: string, createdAt: number, role: OpenViduRole, token: string, location: string, platform: string, serverData: string, clientData: string,
|
||||
publishers: Publisher[], subscribers: string[]) {
|
||||
this.connectionId = connectionId;
|
||||
this.createdAt = createdAt;
|
||||
this.role = role;
|
||||
this.token = token;
|
||||
this.location = location;
|
||||
this.platform = platform;
|
||||
this.serverData = serverData;
|
||||
this.clientData = clientData;
|
||||
this.publishers = publishers;
|
||||
this.subscribers = subscribers;
|
||||
constructor(json) {
|
||||
if (json.publishers != null) {
|
||||
json.publishers.forEach(publisher => {
|
||||
this.publishers.push(new Publisher(publisher));
|
||||
});
|
||||
}
|
||||
if (json.subscribers != null) {
|
||||
json.subscribers.forEach(subscriber => {
|
||||
this.subscribers.push(subscriber.streamId);
|
||||
});
|
||||
}
|
||||
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.createdAt === other.createdAt &&
|
||||
this.role === other.role &&
|
||||
this.serverData === other.serverData &&
|
||||
this.record === other.record &&
|
||||
this.token === other.token &&
|
||||
this.location === other.location &&
|
||||
this.platform === other.platform &&
|
||||
this.serverData === other.serverData &&
|
||||
this.clientData === other.clientData &&
|
||||
this.subscribers.length === other.subscribers.length &&
|
||||
this.publishers.length === other.publishers.length);
|
||||
|
@ -125,4 +141,17 @@ export class Connection {
|
|||
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 { MediaMode } from './MediaMode';
|
||||
import { OpenVidu } from './OpenVidu';
|
||||
import { OpenViduRole } from './OpenViduRole';
|
||||
import { Publisher } from './Publisher';
|
||||
import { Recording } from './Recording';
|
||||
import { RecordingLayout } from './RecordingLayout';
|
||||
import { RecordingMode } from './RecordingMode';
|
||||
import { SessionProperties } from './SessionProperties';
|
||||
import { Token } from './Token';
|
||||
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
|
||||
* **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.forceDisconnect]] automatically updates each affected Connection status
|
||||
* - Calling [[Session.forceUnpublish]] automatically updates each affected local Connection object.
|
||||
* - 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
|
||||
* property [[activeConnections]]
|
||||
|
@ -93,12 +94,36 @@ export class Session {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets a new token associated to Session object
|
||||
*
|
||||
* @returns A Promise that is resolved to the _token_ if success and rejected with an Error object if not
|
||||
* @deprecated Use [[Session.createToken]] instead to get a [[Token]] object.
|
||||
*
|
||||
* @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> {
|
||||
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({
|
||||
session: this.sessionId,
|
||||
|
@ -120,26 +145,13 @@ export class Session {
|
|||
.then(res => {
|
||||
if (res.status === 200) {
|
||||
// SUCCESS response from openvidu-server. Resolve token
|
||||
resolve(res.data.id);
|
||||
resolve(new Token(res.data));
|
||||
} else {
|
||||
// ERROR response from openvidu-server. Resolve HTTP status
|
||||
reject(new Error(res.status.toString()));
|
||||
}
|
||||
}).catch(error => {
|
||||
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));
|
||||
}
|
||||
this.handleError(error, reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -171,29 +183,17 @@ export class Session {
|
|||
reject(new Error(res.status.toString()));
|
||||
}
|
||||
}).catch(error => {
|
||||
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));
|
||||
}
|
||||
this.handleError(error, reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* This applies to any property or sub-property of the Session object
|
||||
|
@ -223,31 +223,27 @@ export class Session {
|
|||
reject(new Error(res.status.toString()));
|
||||
}
|
||||
}).catch(error => {
|
||||
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));
|
||||
}
|
||||
this.handleError(error, reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the user with Connection `connectionId` to leave the session. OpenVidu Browser will trigger the proper events on the client-side
|
||||
* (`streamDestroyed`, `connectionDestroyed`, `sessionDisconnected`) with reason set to `"forceDisconnectByServer"`
|
||||
* Forces the user with Connection `connectionId` to leave the session, or invalidates the [[Token]] associated with that
|
||||
* `connectionId` if no user has used it yet.
|
||||
*
|
||||
* You can get `connection` parameter from [[Session.activeConnections]] array ([[Connection.connectionId]] for getting each `connectionId` property).
|
||||
* Remember to call [[Session.fetch]] before to fetch the current actual properties of the Session from OpenVidu Server
|
||||
* In the first case you can get `connection` parameter from [[Session.activeConnections]] array (remember to call [[Session.fetch]] before
|
||||
* 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
|
||||
*/
|
||||
public forceDisconnect(connection: string | Connection): Promise<any> {
|
||||
|
@ -302,20 +298,7 @@ export class Session {
|
|||
}
|
||||
})
|
||||
.catch(error => {
|
||||
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));
|
||||
}
|
||||
this.handleError(error, reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -327,6 +310,9 @@ export class Session {
|
|||
* 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
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
public forceUnpublish(publisher: string | Publisher): Promise<any> {
|
||||
|
@ -367,20 +353,70 @@ export class Session {
|
|||
reject(new Error(res.status.toString()));
|
||||
}
|
||||
}).catch(error => {
|
||||
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));
|
||||
this.handleError(error, reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = [];
|
||||
json.connections.content.forEach(connection => {
|
||||
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));
|
||||
});
|
||||
json.connections.content.forEach(jsonConnection => this.activeConnections.push(new Connection(jsonConnection)));
|
||||
|
||||
// Order connections by time of creation
|
||||
this.activeConnections.sort((c1, c2) => (c1.createdAt > c2.createdAt) ? 1 : ((c2.createdAt > c1.createdAt) ? -1 : 0));
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* **WARNING**: experimental option. This interface may change in the near future
|
||||
*
|
||||
|
|
|
@ -3,6 +3,7 @@ export * from './OpenViduRole';
|
|||
export * from './Session';
|
||||
export * from './SessionProperties';
|
||||
export * from './TokenOptions';
|
||||
export * from './Token';
|
||||
export * from './MediaMode';
|
||||
export * from './RecordingLayout';
|
||||
export * from './RecordingMode';
|
||||
|
|
Loading…
Reference in New Issue