mirror of https://github.com/OpenVidu/openvidu.git
openvidu-server: RPC Session.forceUnpublish and Session.forceDisconnect
parent
d5958ec906
commit
ff05bb1906
|
@ -175,6 +175,9 @@ public class OpenviduConfig {
|
||||||
case "none":
|
case "none":
|
||||||
roles = new ParticipantRole[0];
|
roles = new ParticipantRole[0];
|
||||||
break;
|
break;
|
||||||
|
case "moderator":
|
||||||
|
roles = new ParticipantRole[] { ParticipantRole.MODERATOR };
|
||||||
|
break;
|
||||||
case "publisher_moderator":
|
case "publisher_moderator":
|
||||||
roles = new ParticipantRole[] { ParticipantRole.PUBLISHER, ParticipantRole.MODERATOR };
|
roles = new ParticipantRole[] { ParticipantRole.PUBLISHER, ParticipantRole.MODERATOR };
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -214,16 +214,18 @@ public class SessionEventsHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUnpublishMedia(Participant participant, Set<Participant> participants, Integer transactionId,
|
public void onUnpublishMedia(Participant participant, Set<Participant> participants, Participant moderator,
|
||||||
OpenViduException error, String reason) {
|
Integer transactionId, OpenViduException error, String reason) {
|
||||||
boolean force = reason.contains("force") || transactionId == null;
|
boolean isRpcFromModerator = transactionId != null && moderator != null;
|
||||||
if (!force) {
|
boolean isRpcFromOwner = transactionId != null && moderator == null;
|
||||||
|
|
||||||
|
if (isRpcFromModerator) {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null,
|
rpcNotificationService.sendErrorResponse(moderator.getParticipantPrivateId(), transactionId, null,
|
||||||
error);
|
error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject());
|
rpcNotificationService.sendResponse(moderator.getParticipantPrivateId(), transactionId, new JsonObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject params = new JsonObject();
|
JsonObject params = new JsonObject();
|
||||||
|
@ -232,21 +234,28 @@ public class SessionEventsHandler {
|
||||||
|
|
||||||
for (Participant p : participants) {
|
for (Participant p : participants) {
|
||||||
if (p.getParticipantPrivateId().equals(participant.getParticipantPrivateId())) {
|
if (p.getParticipantPrivateId().equals(participant.getParticipantPrivateId())) {
|
||||||
if (force) {
|
if (!isRpcFromOwner) {
|
||||||
rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
|
rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
|
||||||
ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params);
|
ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params);
|
||||||
} else {
|
} else {
|
||||||
continue;
|
if (error != null) {
|
||||||
|
rpcNotificationService.sendErrorResponse(p.getParticipantPrivateId(), transactionId, null,
|
||||||
|
error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rpcNotificationService.sendResponse(p.getParticipantPrivateId(), transactionId, new JsonObject());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (error == null) {
|
||||||
rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
|
rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
|
||||||
ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params);
|
ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onSubscribe(Participant participant, Session session, String senderName, String sdpAnswer,
|
public void onSubscribe(Participant participant, Session session, String sdpAnswer, Integer transactionId,
|
||||||
Integer transactionId, OpenViduException error) {
|
OpenViduException error) {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error);
|
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error);
|
||||||
return;
|
return;
|
||||||
|
@ -269,8 +278,7 @@ public class SessionEventsHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUnsubscribe(Participant participant, String senderName, Integer transactionId,
|
public void onUnsubscribe(Participant participant, Integer transactionId, OpenViduException error) {
|
||||||
OpenViduException error) {
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error);
|
rpcNotificationService.sendErrorResponse(participant.getParticipantPrivateId(), transactionId, null, error);
|
||||||
return;
|
return;
|
||||||
|
@ -358,13 +366,30 @@ public class SessionEventsHandler {
|
||||||
rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject());
|
rpcNotificationService.sendResponse(participant.getParticipantPrivateId(), transactionId, new JsonObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onParticipantEvicted(Participant participant, String reason) {
|
public void onForceDisconnect(Participant moderator, Participant evictedParticipant, Set<Participant> participants,
|
||||||
|
Integer transactionId, OpenViduException error, String reason) {
|
||||||
|
|
||||||
|
boolean isRpcCall = transactionId != null;
|
||||||
|
if (isRpcCall) {
|
||||||
|
if (error != null) {
|
||||||
|
rpcNotificationService.sendErrorResponse(moderator.getParticipantPrivateId(), transactionId, null,
|
||||||
|
error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rpcNotificationService.sendResponse(moderator.getParticipantPrivateId(), transactionId, new JsonObject());
|
||||||
|
}
|
||||||
|
|
||||||
JsonObject params = new JsonObject();
|
JsonObject params = new JsonObject();
|
||||||
params.addProperty(ProtocolElements.PARTICIPANTEVICTED_CONNECTIONID_PARAM,
|
params.addProperty(ProtocolElements.PARTICIPANTEVICTED_CONNECTIONID_PARAM,
|
||||||
participant.getParticipantPublicId());
|
evictedParticipant.getParticipantPublicId());
|
||||||
params.addProperty(ProtocolElements.PARTICIPANTEVICTED_REASON_PARAM, reason);
|
params.addProperty(ProtocolElements.PARTICIPANTEVICTED_REASON_PARAM, reason);
|
||||||
rpcNotificationService.sendNotification(participant.getParticipantPrivateId(),
|
|
||||||
|
rpcNotificationService.sendNotification(evictedParticipant.getParticipantPrivateId(),
|
||||||
ProtocolElements.PARTICIPANTEVICTED_METHOD, params);
|
ProtocolElements.PARTICIPANTEVICTED_METHOD, params);
|
||||||
|
for (Participant p : participants) {
|
||||||
|
rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
|
||||||
|
ProtocolElements.PARTICIPANTEVICTED_METHOD, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendRecordingStartedNotification(Session session, Recording recording) {
|
public void sendRecordingStartedNotification(Session session, Recording recording) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ public abstract class SessionManager {
|
||||||
|
|
||||||
public abstract void publishVideo(Participant participant, MediaOptions mediaOptions, Integer transactionId);
|
public abstract void publishVideo(Participant participant, MediaOptions mediaOptions, Integer transactionId);
|
||||||
|
|
||||||
public abstract void unpublishVideo(Participant participant, Integer transactionId, String reason);
|
public abstract void unpublishVideo(Participant participant, Participant moderator, Integer transactionId, String reason);
|
||||||
|
|
||||||
public abstract void subscribe(Participant participant, String senderName, String sdpOffer, Integer transactionId);
|
public abstract void subscribe(Participant participant, String senderName, String sdpOffer, Integer transactionId);
|
||||||
|
|
||||||
|
@ -94,17 +93,10 @@ public abstract class SessionManager {
|
||||||
public abstract void onIceCandidate(Participant participant, String endpointName, String candidate,
|
public abstract void onIceCandidate(Participant participant, String endpointName, String candidate,
|
||||||
int sdpMLineIndex, String sdpMid, Integer transactionId);
|
int sdpMLineIndex, String sdpMid, Integer transactionId);
|
||||||
|
|
||||||
public abstract boolean unpublishStream(Session session, String streamId, String reason);
|
public abstract boolean unpublishStream(Session session, String streamId, Participant moderator, Integer transactionId, String reason);
|
||||||
|
|
||||||
/**
|
public abstract void evictParticipant(Participant evictedParticipant, Participant moderator, Integer transactionId,
|
||||||
* Application-originated request to remove a participant from a session. <br/>
|
String reason);
|
||||||
* <strong>Side effects:</strong> The session event handler should notify the
|
|
||||||
* participant that she has been evicted. Should also send notifications to all
|
|
||||||
* other participants about the one that's just been evicted.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void evictParticipant(String participantPrivateId, String reason) throws OpenViduException {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Session given its id
|
* Returns a Session given its id
|
||||||
|
@ -287,6 +279,18 @@ public abstract class SessionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isModeratorInSession(String sessionId, Participant participant) {
|
||||||
|
if (!this.isInsecureParticipant(participant.getParticipantPrivateId())) {
|
||||||
|
if (this.sessionidParticipantpublicidParticipant.get(sessionId) != null) {
|
||||||
|
return ParticipantRole.MODERATOR.equals(participant.getToken().getRole());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isInsecureParticipant(String participantPrivateId) {
|
public boolean isInsecureParticipant(String participantPrivateId) {
|
||||||
if (this.insecureUsers.containsKey(participantPrivateId)) {
|
if (this.insecureUsers.containsKey(participantPrivateId)) {
|
||||||
log.info("The user with private id {} is an INSECURE user", participantPrivateId);
|
log.info("The user with private id {} is an INSECURE user", participantPrivateId);
|
||||||
|
@ -409,13 +413,11 @@ public abstract class SessionManager {
|
||||||
throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE, "Session '" + sessionId + "' already closed");
|
throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE, "Session '" + sessionId + "' already closed");
|
||||||
}
|
}
|
||||||
Set<Participant> participants = getParticipants(sessionId);
|
Set<Participant> participants = getParticipants(sessionId);
|
||||||
// copy the ids as they will be removed from the map
|
for (Participant p : participants) {
|
||||||
Set<String> pids = participants.stream().map(Participant::getParticipantPrivateId).collect(Collectors.toSet());
|
|
||||||
for (String pid : pids) {
|
|
||||||
try {
|
try {
|
||||||
this.evictParticipant(pid, reason);
|
this.evictParticipant(p, null, null, reason);
|
||||||
} catch (OpenViduException e) {
|
} catch (OpenViduException e) {
|
||||||
log.warn("Error evicting participant with id '{}' from session '{}'", pid, sessionId, e);
|
log.warn("Error evicting participant '{}' from session '{}'", p.getParticipantPublicId(), sessionId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,8 +172,8 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
|
|
||||||
log.info("Last participant left. Stopping recording for session {}", sessionId);
|
log.info("Last participant left. Stopping recording for session {}", sessionId);
|
||||||
recordingService.stopRecording(session);
|
recordingService.stopRecording(session);
|
||||||
evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID)
|
evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID), null,
|
||||||
.getParticipantPrivateId(), "EVICT_RECORDER");
|
null, "EVICT_RECORDER");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally close websocket session if required
|
// Finally close websocket session if required
|
||||||
|
@ -268,7 +268,7 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unpublishVideo(Participant participant, Integer transactionId, String reason) {
|
public void unpublishVideo(Participant participant, Participant moderator, Integer transactionId, String reason) {
|
||||||
try {
|
try {
|
||||||
KurentoParticipant kParticipant = (KurentoParticipant) participant;
|
KurentoParticipant kParticipant = (KurentoParticipant) participant;
|
||||||
KurentoSession session = kParticipant.getSession();
|
KurentoSession session = kParticipant.getSession();
|
||||||
|
@ -283,11 +283,11 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
|
|
||||||
Set<Participant> participants = session.getParticipants();
|
Set<Participant> participants = session.getParticipants();
|
||||||
|
|
||||||
sessionEventsHandler.onUnpublishMedia(participant, participants, transactionId, null, reason);
|
sessionEventsHandler.onUnpublishMedia(participant, participants, moderator, transactionId, null, reason);
|
||||||
|
|
||||||
} catch (OpenViduException e) {
|
} catch (OpenViduException e) {
|
||||||
log.warn("PARTICIPANT {}: Error unpublishing media", participant.getParticipantPublicId(), e);
|
log.warn("PARTICIPANT {}: Error unpublishing media", participant.getParticipantPublicId(), e);
|
||||||
sessionEventsHandler.onUnpublishMedia(participant, null, transactionId, e, "");
|
sessionEventsHandler.onUnpublishMedia(participant, null, moderator, transactionId, e, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,10 +328,10 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
}
|
}
|
||||||
} catch (OpenViduException e) {
|
} catch (OpenViduException e) {
|
||||||
log.error("PARTICIPANT {}: Error subscribing to {}", participant.getParticipantPublicId(), senderName, e);
|
log.error("PARTICIPANT {}: Error subscribing to {}", participant.getParticipantPublicId(), senderName, e);
|
||||||
sessionEventsHandler.onSubscribe(participant, session, senderName, null, transactionId, e);
|
sessionEventsHandler.onSubscribe(participant, session, null, transactionId, e);
|
||||||
}
|
}
|
||||||
if (sdpAnswer != null) {
|
if (sdpAnswer != null) {
|
||||||
sessionEventsHandler.onSubscribe(participant, session, senderName, sdpAnswer, transactionId, null);
|
sessionEventsHandler.onSubscribe(participant, session, sdpAnswer, transactionId, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
|
|
||||||
kParticipant.cancelReceivingMedia(senderName, "unsubscribe");
|
kParticipant.cancelReceivingMedia(senderName, "unsubscribe");
|
||||||
|
|
||||||
sessionEventsHandler.onUnsubscribe(participant, senderName, transactionId, null);
|
sessionEventsHandler.onUnsubscribe(participant, transactionId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -457,19 +457,24 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
sessionEventsHandler.onSessionCreated(sessionId);
|
sessionEventsHandler.onSessionCreated(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Application-originated request to remove a participant from a session. <br/>
|
|
||||||
* <strong>Side effects:</strong> The session event handler should notify the
|
|
||||||
* participant that she has been evicted. Should also send notifications to all
|
|
||||||
* other participants about the one that's just been evicted.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void evictParticipant(String participantPrivateId, String reason) throws OpenViduException {
|
public void evictParticipant(Participant evictedParticipant, Participant moderator, Integer transactionId,
|
||||||
Participant participant = this.getParticipant(participantPrivateId);
|
String reason) throws OpenViduException {
|
||||||
this.leaveRoom(participant, null, reason, false);
|
if (evictedParticipant != null) {
|
||||||
sessionEventsHandler.onParticipantEvicted(participant, reason);
|
KurentoParticipant kParticipant = (KurentoParticipant) evictedParticipant;
|
||||||
sessionEventsHandler.closeRpcSession(participantPrivateId);
|
Set<Participant> participants = kParticipant.getSession().getParticipants();
|
||||||
|
this.leaveRoom(kParticipant, null, reason, false);
|
||||||
|
this.sessionEventsHandler.onForceDisconnect(moderator, evictedParticipant, participants, transactionId,
|
||||||
|
null, reason);
|
||||||
|
sessionEventsHandler.closeRpcSession(evictedParticipant.getParticipantPrivateId());
|
||||||
|
} else {
|
||||||
|
if (moderator != null && transactionId != null) {
|
||||||
|
this.sessionEventsHandler.onForceDisconnect(moderator, evictedParticipant, null, transactionId,
|
||||||
|
new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE,
|
||||||
|
"Connection not found when calling 'forceDisconnect'"),
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -511,12 +516,12 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean unpublishStream(Session session, String streamId, String reason) {
|
public boolean unpublishStream(Session session, String streamId, Participant moderator, Integer transactionId, String reason) {
|
||||||
String participantPrivateId = ((KurentoSession) session).getParticipantPrivateIdFromStreamId(streamId);
|
String participantPrivateId = ((KurentoSession) session).getParticipantPrivateIdFromStreamId(streamId);
|
||||||
if (participantPrivateId != null) {
|
if (participantPrivateId != null) {
|
||||||
Participant participant = this.getParticipant(participantPrivateId);
|
Participant participant = this.getParticipant(participantPrivateId);
|
||||||
if (participant != null) {
|
if (participant != null) {
|
||||||
this.unpublishVideo(participant, null, reason);
|
this.unpublishVideo(participant, moderator, transactionId, reason);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -185,7 +185,7 @@ public class SessionRestController {
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
Participant participant = session.getParticipantByPublicId(participantPublicId);
|
Participant participant = session.getParticipantByPublicId(participantPublicId);
|
||||||
if (participant != null) {
|
if (participant != null) {
|
||||||
this.sessionManager.evictParticipant(participant.getParticipantPrivateId(), "forceDisconnectByServer");
|
this.sessionManager.evictParticipant(participant, null, null, "forceDisconnectByServer");
|
||||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
} else {
|
} else {
|
||||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||||
|
@ -200,7 +200,7 @@ public class SessionRestController {
|
||||||
@PathVariable("streamId") String streamId) {
|
@PathVariable("streamId") String streamId) {
|
||||||
Session session = this.sessionManager.getSession(sessionId);
|
Session session = this.sessionManager.getSession(sessionId);
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
if (this.sessionManager.unpublishStream(session, streamId, "forceUnpublishByServer")) {
|
if (this.sessionManager.unpublishStream(session, streamId, null, null, "forceUnpublishByServer")) {
|
||||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||||
} else {
|
} else {
|
||||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||||
|
@ -331,8 +331,9 @@ public class SessionRestController {
|
||||||
|
|
||||||
Recording stoppedRecording = this.recordingService.stopRecording(session);
|
Recording stoppedRecording = this.recordingService.stopRecording(session);
|
||||||
|
|
||||||
sessionManager.evictParticipant(session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID)
|
sessionManager.evictParticipant(
|
||||||
.getParticipantPrivateId(), "EVICT_RECORDER");
|
session.getParticipantByPublicId(ProtocolElements.RECORDER_PARTICIPANT_PUBLICID), null, null,
|
||||||
|
"EVICT_RECORDER");
|
||||||
|
|
||||||
return new ResponseEntity<>(stoppedRecording.toJson(), HttpStatus.OK);
|
return new ResponseEntity<>(stoppedRecording.toJson(), HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,12 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
case ProtocolElements.STREAMPROPERTYCHANGED_METHOD:
|
case ProtocolElements.STREAMPROPERTYCHANGED_METHOD:
|
||||||
streamPropertyChanged(rpcConnection, request);
|
streamPropertyChanged(rpcConnection, request);
|
||||||
break;
|
break;
|
||||||
|
case ProtocolElements.FORCEDISCONNECT_METHOD:
|
||||||
|
forceDisconnect(rpcConnection, request);
|
||||||
|
break;
|
||||||
|
case ProtocolElements.FORCEUNPUBLISH_METHOD:
|
||||||
|
forceUnpublish(rpcConnection, request);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
log.error("Unrecognized request {}", request);
|
log.error("Unrecognized request {}", request);
|
||||||
break;
|
break;
|
||||||
|
@ -189,36 +195,27 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void leaveRoom(RpcConnection rpcConnection, Request<JsonObject> request) {
|
private void leaveRoom(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
|
try {
|
||||||
|
participant = sanityCheckOfSession(rpcConnection, "disconnect");
|
||||||
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
|
||||||
String sessionId = rpcConnection.getSessionId();
|
|
||||||
|
|
||||||
if (sessionId == null) { // null when afterConnectionClosed
|
|
||||||
log.warn("No session information found for participant with privateId {}. "
|
|
||||||
+ "Using the admin method to evict the user.", participantPrivateId);
|
|
||||||
leaveRoomAfterConnClosed(participantPrivateId, "");
|
|
||||||
} else {
|
|
||||||
// Sanity check: don't call leaveRoom unless the id checks out
|
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
|
||||||
if (participant != null) {
|
|
||||||
log.info("Participant {} is leaving session {}", participant.getParticipantPublicId(), sessionId);
|
|
||||||
sessionManager.leaveRoom(participant, request.getId(), "disconnect", true);
|
sessionManager.leaveRoom(participant, request.getId(), "disconnect", true);
|
||||||
log.info("Participant {} has left session {}", participant.getParticipantPublicId(), sessionId);
|
log.info("Participant {} has left session {}", participant.getParticipantPublicId(),
|
||||||
} else {
|
rpcConnection.getSessionId());
|
||||||
log.warn("Participant with private id {} not found in session {}. "
|
|
||||||
+ "Using the admin method to evict the user.", participantPrivateId, sessionId);
|
|
||||||
leaveRoomAfterConnClosed(participantPrivateId, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publishVideo(RpcConnection rpcConnection, Request<JsonObject> request) {
|
private void publishVideo(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
|
try {
|
||||||
|
participant = sanityCheckOfSession(rpcConnection, "publish");
|
||||||
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
if (sessionManager.isPublisherInSession(rpcConnection.getSessionId(), participant)) {
|
||||||
String sessionId = rpcConnection.getSessionId();
|
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
|
||||||
|
|
||||||
if (sessionManager.isPublisherInSession(sessionId, participant)) {
|
|
||||||
MediaOptions options = sessionManager.generateMediaOptions(request);
|
MediaOptions options = sessionManager.generateMediaOptions(request);
|
||||||
sessionManager.publishVideo(participant, options, request.getId());
|
sessionManager.publishVideo(participant, options, request.getId());
|
||||||
} else {
|
} else {
|
||||||
|
@ -229,10 +226,12 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void receiveVideoFrom(RpcConnection rpcConnection, Request<JsonObject> request) {
|
private void receiveVideoFrom(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
try {
|
||||||
String sessionId = rpcConnection.getSessionId();
|
participant = sanityCheckOfSession(rpcConnection, "subscribe");
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String senderName = getStringParam(request, ProtocolElements.RECEIVEVIDEO_SENDER_PARAM);
|
String senderName = getStringParam(request, ProtocolElements.RECEIVEVIDEO_SENDER_PARAM);
|
||||||
senderName = senderName.substring(0, senderName.indexOf("_"));
|
senderName = senderName.substring(0, senderName.indexOf("_"));
|
||||||
|
@ -242,21 +241,24 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unsubscribeFromVideo(RpcConnection rpcConnection, Request<JsonObject> request) {
|
private void unsubscribeFromVideo(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
try {
|
||||||
String sessionId = rpcConnection.getSessionId();
|
participant = sanityCheckOfSession(rpcConnection, "unsubscribe");
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String senderName = getStringParam(request, ProtocolElements.UNSUBSCRIBEFROMVIDEO_SENDER_PARAM);
|
String senderName = getStringParam(request, ProtocolElements.UNSUBSCRIBEFROMVIDEO_SENDER_PARAM);
|
||||||
|
|
||||||
sessionManager.unsubscribe(participant, senderName, request.getId());
|
sessionManager.unsubscribe(participant, senderName, request.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onIceCandidate(RpcConnection rpcConnection, Request<JsonObject> request) {
|
private void onIceCandidate(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
try {
|
||||||
String sessionId = rpcConnection.getSessionId();
|
participant = sanityCheckOfSession(rpcConnection, "onIceCandidate");
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String endpointName = getStringParam(request, ProtocolElements.ONICECANDIDATE_EPNAME_PARAM);
|
String endpointName = getStringParam(request, ProtocolElements.ONICECANDIDATE_EPNAME_PARAM);
|
||||||
String candidate = getStringParam(request, ProtocolElements.ONICECANDIDATE_CANDIDATE_PARAM);
|
String candidate = getStringParam(request, ProtocolElements.ONICECANDIDATE_CANDIDATE_PARAM);
|
||||||
|
@ -267,29 +269,75 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(RpcConnection rpcConnection, Request<JsonObject> request) {
|
private void sendMessage(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
try {
|
||||||
String sessionId = rpcConnection.getSessionId();
|
participant = sanityCheckOfSession(rpcConnection, "signal");
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String message = getStringParam(request, ProtocolElements.SENDMESSAGE_MESSAGE_PARAM);
|
String message = getStringParam(request, ProtocolElements.SENDMESSAGE_MESSAGE_PARAM);
|
||||||
|
|
||||||
sessionManager.sendMessage(participant, message, request.getId());
|
sessionManager.sendMessage(participant, message, request.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unpublishVideo(RpcConnection rpcConnection, Request<JsonObject> request) {
|
private void unpublishVideo(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
try {
|
||||||
String sessionId = rpcConnection.getSessionId();
|
participant = sanityCheckOfSession(rpcConnection, "unpublish");
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
sessionManager.unpublishVideo(participant, request.getId(), "unpublish");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void streamPropertyChanged(RpcConnection rpcConnection, Request<JsonObject> request) {
|
sessionManager.unpublishVideo(participant, null, request.getId(), "unpublish");
|
||||||
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
}
|
||||||
String sessionId = rpcConnection.getSessionId();
|
|
||||||
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
private void forceDisconnect(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
|
try {
|
||||||
|
participant = sanityCheckOfSession(rpcConnection, "forceDisconnect");
|
||||||
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessionManager.isModeratorInSession(rpcConnection.getSessionId(), participant)) {
|
||||||
|
String connectionId = getStringParam(request, ProtocolElements.FORCEDISCONNECT_CONNECTIONID_PARAM);
|
||||||
|
sessionManager.evictParticipant(
|
||||||
|
sessionManager.getSession(rpcConnection.getSessionId()).getParticipantByPublicId(connectionId),
|
||||||
|
participant, request.getId(), "forceDisconnectByUser");
|
||||||
|
} else {
|
||||||
|
log.error("Error: participant {} is not a moderator", participant.getParticipantPublicId());
|
||||||
|
throw new OpenViduException(Code.USER_UNAUTHORIZED_ERROR_CODE,
|
||||||
|
"Unable to force disconnect. The user does not have a valid token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void forceUnpublish(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
|
try {
|
||||||
|
participant = sanityCheckOfSession(rpcConnection, "forceUnpublish");
|
||||||
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sessionManager.isModeratorInSession(rpcConnection.getSessionId(), participant)) {
|
||||||
|
String streamId = getStringParam(request, ProtocolElements.FORCEUNPUBLISH_STREAMID_PARAM);
|
||||||
|
sessionManager.unpublishStream(sessionManager.getSession(rpcConnection.getSessionId()), streamId,
|
||||||
|
participant, request.getId(), "forceUnpublishByUser");
|
||||||
|
} else {
|
||||||
|
log.error("Error: participant {} is not a moderator", participant.getParticipantPublicId());
|
||||||
|
throw new OpenViduException(Code.USER_UNAUTHORIZED_ERROR_CODE,
|
||||||
|
"Unable to force unpublish. The user does not have a valid token");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void streamPropertyChanged(RpcConnection rpcConnection, Request<JsonObject> request) {
|
||||||
|
Participant participant;
|
||||||
|
try {
|
||||||
|
participant = sanityCheckOfSession(rpcConnection, "onStreamPropertyChanged");
|
||||||
|
} catch (OpenViduException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String streamId = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_STREAMID_PARAM);
|
String streamId = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_STREAMID_PARAM);
|
||||||
String property = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_PROPERTY_PARAM);
|
String property = getStringParam(request, ProtocolElements.STREAMPROPERTYCHANGED_PROPERTY_PARAM);
|
||||||
|
@ -301,7 +349,8 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
|
|
||||||
public void leaveRoomAfterConnClosed(String participantPrivateId, String reason) {
|
public void leaveRoomAfterConnClosed(String participantPrivateId, String reason) {
|
||||||
try {
|
try {
|
||||||
sessionManager.evictParticipant(participantPrivateId, reason);
|
sessionManager.evictParticipant(this.sessionManager.getParticipant(participantPrivateId), null, null,
|
||||||
|
reason);
|
||||||
log.info("Evicted participant with privateId {}", participantPrivateId);
|
log.info("Evicted participant with privateId {}", participantPrivateId);
|
||||||
} catch (OpenViduException e) {
|
} catch (OpenViduException e) {
|
||||||
log.warn("Unable to evict: {}", e.getMessage());
|
log.warn("Unable to evict: {}", e.getMessage());
|
||||||
|
@ -409,4 +458,33 @@ public class RpcHandler extends DefaultJsonRpcHandler<JsonObject> {
|
||||||
return request.getParams().get(key);
|
return request.getParams().get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Participant sanityCheckOfSession(RpcConnection rpcConnection, String methodName) throws OpenViduException {
|
||||||
|
String participantPrivateId = rpcConnection.getParticipantPrivateId();
|
||||||
|
String sessionId = rpcConnection.getSessionId();
|
||||||
|
String errorMsg;
|
||||||
|
|
||||||
|
if (sessionId == null) { // null when afterConnectionClosed
|
||||||
|
errorMsg = "No session information found for participant with privateId " + participantPrivateId
|
||||||
|
+ ". Using the admin method to evict the user.";
|
||||||
|
log.warn(errorMsg);
|
||||||
|
leaveRoomAfterConnClosed(participantPrivateId, "");
|
||||||
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE, errorMsg);
|
||||||
|
} else {
|
||||||
|
// Sanity check: don't call RPC method unless the id checks out
|
||||||
|
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
|
||||||
|
if (participant != null) {
|
||||||
|
errorMsg = "Participant " + participant.getParticipantPublicId() + " is calling method '" + methodName
|
||||||
|
+ "' in session " + sessionId;
|
||||||
|
log.info(errorMsg);
|
||||||
|
return participant;
|
||||||
|
} else {
|
||||||
|
errorMsg = "Participant with private id " + participantPrivateId + " not found in session " + sessionId
|
||||||
|
+ ". Using the admin method to evict the user.";
|
||||||
|
log.warn(errorMsg);
|
||||||
|
leaveRoomAfterConnClosed(participantPrivateId, "");
|
||||||
|
throw new OpenViduException(Code.GENERIC_ERROR_CODE, errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue