openvidu-server: RPC Session.forceUnpublish and Session.forceDisconnect

pull/88/merge
pabloFuente 2018-07-09 15:49:27 +02:00
parent d5958ec906
commit ff05bb1906
6 changed files with 227 additions and 113 deletions

View File

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

View File

@ -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 {
rpcNotificationService.sendNotification(p.getParticipantPrivateId(), if (error == null) {
ProtocolElements.PARTICIPANTUNPUBLISHED_METHOD, params); rpcNotificationService.sendNotification(p.getParticipantPrivateId(),
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) {

View File

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

View File

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

View File

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

View File

@ -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;
String participantPrivateId = rpcConnection.getParticipantPrivateId(); try {
String sessionId = rpcConnection.getSessionId(); participant = sanityCheckOfSession(rpcConnection, "disconnect");
} catch (OpenViduException e) {
if (sessionId == null) { // null when afterConnectionClosed return;
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);
log.info("Participant {} has left session {}", participant.getParticipantPublicId(), sessionId);
} else {
log.warn("Participant with private id {} not found in session {}. "
+ "Using the admin method to evict the user.", participantPrivateId, sessionId);
leaveRoomAfterConnClosed(participantPrivateId, "");
}
} }
sessionManager.leaveRoom(participant, request.getId(), "disconnect", true);
log.info("Participant {} has left session {}", participant.getParticipantPublicId(),
rpcConnection.getSessionId());
} }
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;
try {
participant = sanityCheckOfSession(rpcConnection, "unpublish");
} catch (OpenViduException e) {
return;
}
String participantPrivateId = rpcConnection.getParticipantPrivateId(); sessionManager.unpublishVideo(participant, null, request.getId(), "unpublish");
String sessionId = rpcConnection.getSessionId();
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId);
sessionManager.unpublishVideo(participant, request.getId(), "unpublish");
} }
public void streamPropertyChanged(RpcConnection rpcConnection, Request<JsonObject> request) { private void forceDisconnect(RpcConnection rpcConnection, Request<JsonObject> request) {
String participantPrivateId = rpcConnection.getParticipantPrivateId(); Participant participant;
String sessionId = rpcConnection.getSessionId(); try {
Participant participant = sessionManager.getParticipant(sessionId, participantPrivateId); 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);
}
}
}
} }