ask akka-apps if allowed to start screenshare

This commit is contained in:
Anton Georgiev 2016-08-11 19:18:56 +00:00
parent 5eccf9297b
commit f7cb97737d
17 changed files with 182 additions and 82 deletions

View File

@ -40,6 +40,7 @@ public interface IBigBlueButtonInGW {
void userLeft(String meetingID, String userID, String sessionId);
void userJoin(String meetingID, String userID, String authToken);
void getCurrentPresenter(String meetingID, String requesterID);
void checkIfAllowedToShareDesktop(String meetingID, String userID);
void assignPresenter(String meetingID, String newPresenterID, String newPresenterName, String assignedBy);
void setRecordingStatus(String meetingId, String userId, Boolean recording);
void getRecordingStatus(String meetingId, String userId);

View File

@ -33,6 +33,9 @@ public class UsersMessageReceiver implements MessageHandler{
case UserLeavingMessage.USER_LEAVING:
processUserLeavingMessage(message);
break;
case AllowUserToShareDesktopRequest.NAME:
processAllowUserToShareDesktopRequest(message);
break;
case AssignPresenterRequestMessage.ASSIGN_PRESENTER_REQUEST:
processAssignPresenterRequestMessage(message);
break;
@ -194,6 +197,13 @@ public class UsersMessageReceiver implements MessageHandler{
}
}
private void processAllowUserToShareDesktopRequest(String message) {
AllowUserToShareDesktopRequest msg = AllowUserToShareDesktopRequest.fromJson(message);
if (msg != null) {
bbbInGW.checkIfAllowedToShareDesktop(msg.meetingId, msg.userId);
}
}
private void processAssignPresenterRequestMessage(String message) {
AssignPresenterRequestMessage apm = AssignPresenterRequestMessage.fromJson(message);
if (apm != null) {

View File

@ -242,6 +242,11 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent(meetingID, new UserJoining(meetingID, userID, authToken)))
}
def checkIfAllowedToShareDesktop(meetingID: String, userID: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, AllowUserToShareDesktop(meetingID: String,
userID: String)))
}
def assignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String): Unit = {
eventBus.publish(BigBlueButtonEvent(meetingID, new AssignPresenter(meetingID, newPresenterID, newPresenterName, assignedBy)))
}

View File

@ -125,6 +125,16 @@ class LiveMeeting(val mProps: MeetingProperties,
outGW.send(new DisconnectAllUsers(msg.meetingId))
}
def handleAllowUserToShareDesktop(msg: AllowUserToShareDesktop): Unit = {
usersModel.getCurrentPresenter() match {
case Some(curPres) => {
val allowed = msg.userID equals (curPres.userID)
outGW.send(AllowUserToShareDesktopOut(msg.meetingID, msg.userID, allowed))
}
case None => // do nothing
}
}
def handleVoiceConfRecordingStartedMessage(msg: VoiceConfRecordingStartedMessage) {
if (msg.recording) {
meetingModel.setVoiceRecordingFilename(msg.recordStream)

View File

@ -105,6 +105,7 @@ class MeetingActor(val mProps: MeetingProperties,
case msg: UserJoining => liveMeeting.handleUserJoin(msg)
case msg: UserLeaving => liveMeeting.handleUserLeft(msg)
case msg: AssignPresenter => liveMeeting.handleAssignPresenter(msg)
case msg: AllowUserToShareDesktop => liveMeeting.handleAllowUserToShareDesktop(msg)
case msg: GetUsers => liveMeeting.handleGetUsers(msg)
case msg: ChangeUserStatus => liveMeeting.handleChangeUserStatus(msg)
case msg: EjectUserFromMeeting => liveMeeting.handleEjectUserFromMeeting(msg)

View File

@ -15,7 +15,9 @@ import org.bigbluebutton.core.pubsub.senders.CaptionMessageToJsonConverter
import org.bigbluebutton.core.pubsub.senders.DeskShareMessageToJsonConverter
import org.bigbluebutton.common.messages.GetPresentationInfoReplyMessage
import org.bigbluebutton.common.messages.PresentationRemovedMessage
import org.bigbluebutton.common.messages.AllowUserToShareDesktopReply
import org.bigbluebutton.core.apps.Page
import collection.JavaConverters._
import scala.collection.JavaConversions._
import org.bigbluebutton.core.apps.SimplePollResultOutVO
@ -31,6 +33,7 @@ import org.bigbluebutton.common.messages.LockLayoutMessage
import org.bigbluebutton.core.pubsub.senders.WhiteboardMessageToJsonConverter
import org.bigbluebutton.common.converters.ToJsonEncoder
import org.bigbluebutton.common.messages.TransferUserToVoiceConfRequestMessage
import org.bigbluebutton.core
object MessageSenderActor {
def props(msgSender: MessageSender): Props =
@ -82,6 +85,7 @@ class MessageSenderActor(val service: MessageSender)
case msg: MeetingMuted => handleMeetingMuted(msg)
case msg: MeetingState => handleMeetingState(msg)
case msg: DisconnectAllUsers => handleDisconnectAllUsers(msg)
case msg: AllowUserToShareDesktopOut => handleAllowUserToShareDesktopOut(msg)
case msg: DisconnectUser => handleDisconnectUser(msg)
case msg: PermissionsSettingInitialized => handlePermissionsSettingInitialized(msg)
case msg: NewPermissionsSetting => handleNewPermissionsSetting(msg)
@ -535,6 +539,13 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleAllowUserToShareDesktopOut(msg: AllowUserToShareDesktopOut): Unit = {
val obj = new AllowUserToShareDesktopReply(msg.meetingID, msg.userID, msg.allowed,
TimestampGenerator.generateTimestamp)
val json = obj.toJson()
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handlePermissionsSettingInitialized(msg: PermissionsSettingInitialized) {
val json = UsersMessageToJsonConverter.permissionsSettingInitializedToJson(msg)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)

View File

@ -90,6 +90,7 @@ case class ChangeUserStatus(meetingID: String, userID: String, status: String, v
case class AssignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String) extends InMessage
case class SetRecordingStatus(meetingID: String, userId: String, recording: Boolean) extends InMessage
case class GetRecordingStatus(meetingID: String, userId: String) extends InMessage
case class AllowUserToShareDesktop(meetingID: String, userID: String) extends InMessage
//////////////////////////////////////////////////////////////////////////////////
// Chat

View File

@ -73,6 +73,7 @@ case class EjectVoiceUser(meetingID: String, recorded: Boolean, requesterID: Str
case class TransferUserToMeeting(voiceConfId: String, targetVoiceConfId: String, userId: String) extends IOutMessage
case class UserJoinedVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserLeftVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class AllowUserToShareDesktopOut(meetingID: String, userID: String, allowed: Boolean) extends IOutMessage
// Voice
case class IsMeetingMutedReply(meetingID: String, recorded: Boolean, requesterID: String, meetingMuted: Boolean) extends IOutMessage

View File

@ -0,0 +1,66 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class AllowUserToShareDesktopReply implements ISubscribedMessage {
public static final String NAME = "AllowUserToShareDesktopReply";
public static final String VERSION = "0.0.1";
public static final String TIMESTAMP = "timestamp";
public static final String MEETING_ID = "meeting_id";
public static final String USER_ID = "user_id";
public static final String ALLOWED = "allowed";
public final Long timestamp;
public final String userId;
public final String meetingId;
public final Boolean allowed;
public AllowUserToShareDesktopReply(String meetingId, String userId,
Boolean allowed, Long timestamp) {
this.meetingId = meetingId;
this.userId = userId;
this.allowed = allowed;
this.timestamp = timestamp;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(TIMESTAMP, timestamp);
payload.put(MEETING_ID, meetingId);
payload.put(USER_ID, userId);
payload.put(ALLOWED, allowed);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(NAME, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static AllowUserToShareDesktopReply fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (NAME.equals(messageName)) {
if (payload.has(TIMESTAMP) && payload.has(MEETING_ID)
&& payload.has(USER_ID) && payload.has(ALLOWED)) {
Long timestamp = payload.get(TIMESTAMP).getAsLong();
String meetingId = payload.get(MEETING_ID).getAsString();
String userId = payload.get(USER_ID).getAsString();
Boolean allowed = payload.get(ALLOWED).getAsBoolean();
return new AllowUserToShareDesktopReply(meetingId, userId, allowed,
timestamp);
}
}
}
}
return null;
}
}

View File

@ -35,7 +35,7 @@ public class MessageReceiver {
jedis = new Jedis(host, port);
// Set the name of this client to be able to distinguish when doing
// CLIENT LIST on redis-cli
jedis.clientSetname("BbbRed5AppsSub");
jedis.clientSetname("bbb-screenshare");
Runnable messageReceiver = new Runnable() {
public void run() {

View File

@ -1,75 +1,46 @@
package org.bigbluebutton.app.screenshare.messaging.redis;
//import org.bigbluebutton.common.messages.MessagingConstants;
//import org.bigbluebutton.red5.client.MeetingClientMessageSender;
//import org.bigbluebutton.red5.client.PollingClientMessageSender;
//import org.bigbluebutton.red5.client.PresentationClientMessageSender;
//import org.bigbluebutton.red5.client.UserClientMessageSender;
//import org.bigbluebutton.red5.client.ChatClientMessageSender;
//import org.bigbluebutton.red5.client.WhiteboardClientMessageSender;
//import org.bigbluebutton.red5.client.CaptionClientMessageSender;
//import org.bigbluebutton.red5.client.DeskShareMessageSender;
//import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
//import org.bigbluebutton.red5.monitoring.BbbAppsIsKeepAliveHandler;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bigbluebutton.app.screenshare.red5.Red5AppHandler;
import org.bigbluebutton.common.messages.AllowUserToShareDesktopReply;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
public class RedisPubSubMessageHandler implements MessageHandler {
private static Logger log = Red5LoggerFactory.getLogger(RedisPubSubMessageHandler.class, "bigbluebutton");
private static Logger log = Red5LoggerFactory.getLogger(RedisPubSubMessageHandler.class,
"screenshare");
private Red5AppHandler handler;
// private ConnectionInvokerService service;
// private UserClientMessageSender userMessageSender;
// private MeetingClientMessageSender meetingMessageSender;
// private ChatClientMessageSender chatMessageSender;
// private PresentationClientMessageSender presentationMessageSender;
// private WhiteboardClientMessageSender whiteboardMessageSender;
// private DeskShareMessageSender deskShareMessageSender;
// private BbbAppsIsKeepAliveHandler bbbAppsIsKeepAliveHandler;
// private PollingClientMessageSender pollingMessageSender;
// private CaptionClientMessageSender captionMessageSender;
// public void setConnectionInvokerService(ConnectionInvokerService s) {
// this.service = s;
// userMessageSender = new UserClientMessageSender(service);
// meetingMessageSender = new MeetingClientMessageSender(service);
// chatMessageSender = new ChatClientMessageSender(service);
// presentationMessageSender = new PresentationClientMessageSender(service);
// whiteboardMessageSender = new WhiteboardClientMessageSender(service);
// deskShareMessageSender = new DeskShareMessageSender(service);
// pollingMessageSender = new PollingClientMessageSender(service);
// captionMessageSender = new CaptionClientMessageSender(service);
// }
//
// public void setBbbAppsIsKeepAliveHandler(BbbAppsIsKeepAliveHandler handler) {
// bbbAppsIsKeepAliveHandler = handler;
// }
//
@Override
public void handleMessage(String pattern, String channel, String message) {
System.out.println("___RedisPubSubMessageHandler:::in red5 getting message: " + channel +
" " + message);
log.info("___RedisPubSubMessageHandler:::in red5 getting message: " + channel + " " +
message);
// if (channel.equalsIgnoreCase(MessagingConstants.FROM_CHAT_CHANNEL)) {
// chatMessageSender.handleChatMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_PRESENTATION_CHANNEL)) {
// presentationMessageSender.handlePresentationMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_MEETING_CHANNEL)) {
// meetingMessageSender.handleMeetingMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_USERS_CHANNEL)) {
// log.info("trace 0 : " + message);
// userMessageSender.handleUsersMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_WHITEBOARD_CHANNEL)) {
// whiteboardMessageSender.handleWhiteboardMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_SYSTEM_CHANNEL)) {
// bbbAppsIsKeepAliveHandler.handleKeepAliveMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_DESK_SHARE_CHANNEL)) {
// deskShareMessageSender.handleDeskShareMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_POLLING_CHANNEL)) {
// pollingMessageSender.handlePollMessage(message);
// } else if (channel.equalsIgnoreCase(MessagingConstants.FROM_CAPTION_CHANNEL)) {
// captionMessageSender.handleCaptionMessage(message);
// }
if (channel.equalsIgnoreCase(MessagingConstants.FROM_MEETING_CHANNEL)) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (AllowUserToShareDesktopReply.NAME.equals(messageName)) {
AllowUserToShareDesktopReply msg = AllowUserToShareDesktopReply.fromJson(message);
log.info("^^^^^^^AllowUserToShareDesktopReply in " +
"RedisPubSubMessageHandler::handleMessage^^^^^^allowed=" + msg.allowed);
handler.startShareRequest(msg.meetingId, msg.userId, msg.allowed);
} else {
log.info("some other meeting message");
}
}
}
}
}
public void setAppHandler(Red5AppHandler handler) {
this.handler = handler;
}
}

View File

@ -41,11 +41,13 @@ public class Red5AppHandler {
sender.sendMessage(msg);
}
public void startShareRequest(String meetingId, String userId, Boolean record) {
StartShareRequestResponse resp = app.startShareRequest(meetingId, userId, record);
public void startShareRequest(String meetingId, String userId, Boolean allowed) {
StartShareRequestResponse resp = app.startShareRequest(meetingId, userId, allowed);
Map<String, Object> data = new HashMap<String, Object>();
data.put("allowed", allowed);
if (resp.error != null) {
data.put("error", resp.error.reason);
} else {

View File

@ -6,6 +6,9 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.bigbluebutton.app.screenshare.messaging.redis.MessageSender;
//import org.bigbluebutton.app.screenshare.messaging.redis.MessagingConstants;
import org.bigbluebutton.common.messages.AllowUserToShareDesktopRequest;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.IConnection;
import org.red5.server.api.Red5;
@ -98,10 +101,15 @@ public class Red5AppService {
event.put("meetingId", meetingId);
event.put("userID", userId);
event.put("eventName", "AllowUserToShareDesktopRequest");
// red5RedisSender.record(meetingId, event);
// red5RedisSender.record(meetingId, event); TODO
AllowUserToShareDesktopRequest requestMsg = new AllowUserToShareDesktopRequest(meetingId,
userId,
genTimestamp());
red5RedisSender.send(MessagingConstants.TO_USERS_CHANNEL, requestMsg.toJson());
log.info("_______Red5AppService::startShareRequest");
// handler.startShareRequest(meetingId, userId, record);
// handler.startShareRequest(meetingId, userId, record); //TODO REMOVE
}
public void stopShareRequest(Map<String, Object> msg) {

View File

@ -90,12 +90,17 @@ class ScreenShareApplication(val bus: IEventsMessageBus, val jnlpFile: String,
if (logger.isDebugEnabled()) {
logger.debug("Received start share request on meeting=" + meetingId + "for user=" + userId + "]")
}
implicit val timeout = Timeout(3 seconds)
val future = screenshareManager ? StartShareRequestMessage(meetingId, userId, record)
val reply = Await.result(future, timeout.duration).asInstanceOf[StartShareRequestReplyMessage]
if (record) {
implicit val timeout = Timeout(3 seconds)
val future = screenshareManager ? StartShareRequestMessage(meetingId, userId, record)
val reply = Await.result(future, timeout.duration).asInstanceOf[StartShareRequestReplyMessage]
val response = new StartShareRequestResponse(reply.token, jnlpFile, null)
response
} else {
new StartShareRequestResponse("none", "none", null) // was not allowed to share desktop
}
val response = new StartShareRequestResponse(reply.token, jnlpFile, null)
response
}
def stopShareRequest(meetingId: String, streamId: String) {

View File

@ -223,6 +223,10 @@ class Screenshare(val sessionManager: ScreenshareManager,
}
private def handleStartShareRequestMessage(msg: StartShareRequestMessage) {
val token = RandomStringGenerator.randomAlphanumericString(16)
val streamId = msg.meetingId + "-" + System.currentTimeMillis()
val session = ActiveSession(this, bus, meetingId, streamId, token, msg.record, msg.userId)
@ -230,7 +234,8 @@ class Screenshare(val sessionManager: ScreenshareManager,
sessions += streamId -> session
session.actorRef ! msg
sender ! new StartShareRequestReplyMessage(token)
sender ! new StartShareRequestReplyMessage(token) // todo use forward here
// todo remove Request from the name of the case class
}
private def handleIsSharingStopped(msg: IsSharingStopped) {

View File

@ -111,8 +111,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<bean id="redisPubSubMessageHandler"
class="org.bigbluebutton.app.screenshare.messaging.redis.RedisPubSubMessageHandler">
<!--<property name="connectionInvokerService"> <ref bean="connInvokerService"/></property>-->
<!--<property name="bbbAppsIsKeepAliveHandler"> <ref bean="bbbAppsIsKeepAliveHandler"/></property>-->
<property name="appHandler" ref="red5AppHandler"/>
</bean>
<import resource="bbb-redis-pool.xml"/>

View File

@ -73,7 +73,11 @@ package org.bigbluebutton.modules.screenshare.services
private function handleStartShareRequestResponse(message:Object):void {
LOGGER.debug("handleStartShareRequestResponse " + message);
var map:Object = JSON.parse(message.msg);
if (map.hasOwnProperty("authToken") && map.hasOwnProperty("jnlp")) {
if (map.hasOwnProperty("allowed") &&
map.allowed &&
map.hasOwnProperty("authToken") &&
map.hasOwnProperty("jnlp")) {
var shareSuccessEvent: ShareStartRequestResponseEvent = new ShareStartRequestResponseEvent(map.authToken, map.jnlp, true);
dispatcher.dispatchEvent(shareSuccessEvent);
} else {