Permalink
Browse files

Working on avoiding reconnection when ending a meeting by API call

  • Loading branch information...
1 parent f36ea5b commit 14b480c8cecd353909fc91f621c56534d514921a @pedrobmarin pedrobmarin committed Dec 9, 2016
@@ -9,6 +9,8 @@ import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.api._
import org.bigbluebutton.SystemConfiguration
+import java.util.concurrent.TimeUnit
+
object BigBlueButtonActor extends SystemConfiguration {
def props(system: ActorSystem,
eventBus: IncomingEventBus,
@@ -126,17 +128,21 @@ class BigBlueButtonActor(val system: ActorSystem,
outGW.send(new EndAndKickAll(msg.meetingID, m.mProps.recorded))
// Eject all users from the voice conference
outGW.send(new EjectAllVoiceUsers(msg.meetingID, m.mProps.recorded, m.mProps.voiceBridge))
- // Disconnect all clients
- outGW.send(new DisconnectAllUsers(msg.meetingID))
- log.info("Destroyed meetingId={}", msg.meetingID)
- outGW.send(new MeetingDestroyed(msg.meetingID))
- /** Unsubscribe to meeting and voice events. **/
- eventBus.unsubscribe(m.actorRef, m.mProps.meetingID)
- eventBus.unsubscribe(m.actorRef, m.mProps.voiceBridge)
+ // Delay sending DisconnectAllUsers because of RTMPT connection being dropped before UserEject message arrives to the client
+ context.system.scheduler.scheduleOnce(Duration.create(2500, TimeUnit.MILLISECONDS)) {
+ // Disconnect all clients
+ outGW.send(new DisconnectAllUsers(msg.meetingID))
+ log.info("Destroyed meetingId={}", msg.meetingID)
+ outGW.send(new MeetingDestroyed(msg.meetingID))
+
+ /** Unsubscribe to meeting and voice events. **/
+ eventBus.unsubscribe(m.actorRef, m.mProps.meetingID)
+ eventBus.unsubscribe(m.actorRef, m.mProps.voiceBridge)
- // Stop the meeting actor.
- context.stop(m.actorRef)
+ // Stop the meeting actor.
+ context.stop(m.actorRef)
+ }
}
}
}
@@ -114,24 +114,12 @@ class LiveMeeting(val mProps: MeetingProperties,
}
def handleEndMeeting(msg: EndMeeting) {
- meetingModel.meetingHasEnded
+ // Broadcast users the meeting will end
+ outGW.send(new MeetingEnding(msg.meetingId))
- /**
- * Check if this meeting has breakout rooms. If so, we also need to end them.
- */
- handleEndAllBreakoutRooms(new EndAllBreakoutRooms(msg.meetingId))
+ meetingModel.meetingHasEnded
outGW.send(new MeetingEnded(msg.meetingId, mProps.recorded, mProps.voiceBridge))
-
- // Eject users from the voice conference.
- outGW.send(new EjectAllVoiceUsers(mProps.meetingID, mProps.recorded, mProps.voiceBridge))
-
- // Delay sending DisconnectAllUsers because of RTMPT connection being dropped before UserEject message arrives to the client
- import context.dispatcher
- context.system.scheduler.scheduleOnce(Duration.create(2500, TimeUnit.MILLISECONDS)) {
- log.info("Sending delayed DisconnectUser. meetingId={}", mProps.meetingID)
- outGW.send(new DisconnectAllUsers(msg.meetingId))
- }
}
def handleAllowUserToShareDesktop(msg: AllowUserToShareDesktop): Unit = {
@@ -54,6 +54,7 @@ class MessageSenderActor(val service: MessageSender)
case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg)
case msg: RecordingStatusChanged => handleRecordingStatusChanged(msg)
case msg: GetRecordingStatusReply => handleGetRecordingStatusReply(msg)
+ case msg: MeetingEnding => handleMeetingEnding(msg)
case msg: MeetingEnded => handleMeetingEnded(msg)
case msg: MeetingHasEnded => handleMeetingHasEnded(msg)
case msg: MeetingDestroyed => handleMeetingDestroyed(msg)
@@ -221,7 +222,12 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
val json2 = UsersMessageToJsonConverter.meetingEnded(msg)
- service.send(MessagingConstants.FROM_MEETING_CHANNEL, json2)
+ service.send(MessagingConstants.FROM_USERS_CHANNEL, json2)
+ }
+
+ private def handleMeetingEnding(msg: MeetingEnding) {
+ val json = MeetingMessageToJsonConverter.meetingEndingToJson(msg)
+ service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def handleStartRecording(msg: StartRecording) {
@@ -265,7 +271,7 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
val json2 = UsersMessageToJsonConverter.meetingHasEnded(msg)
- service.send(MessagingConstants.FROM_MEETING_CHANNEL, json2)
+ service.send(MessagingConstants.FROM_USERS_CHANNEL, json2)
}
private def handleGetAllMeetingsReply(msg: GetAllMeetingsReply) {
@@ -87,6 +87,7 @@ object MessageNames {
val VOICE_RECORDING_STOPPED = "voice_recording_stopped_message"
val RECORDING_STATUS_CHANGED = "recording_status_changed_message"
val GET_RECORDING_STATUS_REPLY = "get_recording_status_reply"
+ val MEETING_ENDING = "meeting_ending_message"
val MEETING_ENDED = "meeting_ended_message"
val MEETING_HAS_ENDED = "meeting_has_ended_message"
val MEETING_STATE = "meeting_state_message"
@@ -17,6 +17,7 @@ case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId:
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
+case class MeetingEnding(meetingID: String) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
case class MeetingHasEnded(meetingID: String, userId: String) extends IOutMessage
@@ -52,6 +52,14 @@ object MeetingMessageToJsonConverter {
Util.buildJson(header, payload)
}
+ def meetingEndingToJson(msg: MeetingEnding): String = {
+ val payload = new java.util.HashMap[String, Any]()
+ payload.put(Constants.MEETING_ID, msg.meetingID)
+
+ val header = Util.buildHeader(MessageNames.MEETING_ENDING, None)
+ Util.buildJson(header, payload)
+ }
+
def voiceRecordingStartedToJson(msg: VoiceRecordingStarted): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
@@ -0,0 +1,48 @@
+package org.bigbluebutton.common.messages;
+
+import java.util.HashMap;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+public class MeetingEndingMessage implements ISubscribedMessage {
+ public static final String MEETING_ENDING = "meeting_ending_message";
+ public final String VERSION = "0.0.1";
+
+ public final String meetingId;
+
+ public MeetingEndingMessage(String meetingID) {
+ this.meetingId = meetingID;
+ }
+
+ public String toJson() {
+ HashMap<String, Object> payload = new HashMap<String, Object>();
+ payload.put(Constants.MEETING_ID, meetingId);
+
+ java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(MEETING_ENDING, VERSION, null);
+
+ return MessageBuilder.buildJson(header, payload);
+ }
+ public static MeetingEndingMessage 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 (MEETING_ENDING.equals(messageName)) {
+ if (payload.has(Constants.MEETING_ID)) {
+ String meetingId = payload.get(Constants.MEETING_ID).getAsString();
+
+ return new MeetingEndingMessage(meetingId);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+}
@@ -7,6 +7,7 @@
import org.bigbluebutton.common.messages.DisconnectAllUsersMessage;
import org.bigbluebutton.common.messages.DisconnectUserMessage;
import org.bigbluebutton.common.messages.MeetingEndedMessage;
+import org.bigbluebutton.common.messages.MeetingEndingMessage;
import org.bigbluebutton.common.messages.MeetingHasEndedMessage;
import org.bigbluebutton.common.messages.MeetingMutedMessage;
import org.bigbluebutton.common.messages.MeetingStateMessage;
@@ -58,6 +59,12 @@ public void handleMeetingMessage(String message) {
processMeetingEndedMessage(mem);
}
break;
+ case MeetingEndingMessage.MEETING_ENDING:
+ MeetingEndingMessage me = MeetingEndingMessage.fromJson(message);
+ if (me != null) {
+ processMeetingEndingMessage(me);
+ }
+ break;
case MeetingHasEndedMessage.MEETING_HAS_ENDED:
MeetingHasEndedMessage mhem = MeetingHasEndedMessage.fromJson(message);
if (mhem != null) {
@@ -162,6 +169,18 @@ private void processMeetingEndedMessage(MeetingEndedMessage msg) {
service.sendMessage(m);
}
+ private void processMeetingEndingMessage(MeetingEndingMessage msg) {
+ Map<String, Object> args = new HashMap<String, Object>();
+ args.put("status", "Meeting is ending.");
+
+ Map<String, Object> message = new HashMap<String, Object>();
+ Gson gson = new Gson();
+ message.put("msg", gson.toJson(args));
+
+ BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "meetingEnding", message);
+ service.sendMessage(m);
+ }
+
private void processDisconnectAllUsersMessage(DisconnectAllUsersMessage msg) {
DisconnectAllClientsMessage dm = new DisconnectAllClientsMessage(msg.meetingId);
service.sendMessage(dm);
@@ -76,6 +76,9 @@ package org.bigbluebutton.modules.users.services
case "meetingEnded":
handleLogout(message);
break;
+ case "meetingEnding":
+ handleMeetingEnding(message);
+ break;
case "meetingHasEnded":
handleMeetingHasEnded(message);
break;
@@ -453,6 +456,15 @@ package org.bigbluebutton.modules.users.services
dispatcher.dispatchEvent(endMeetingEvent);
}
+ /**
+ * This meeting is in the process of ending by the server
+ */
+ public function handleMeetingEnding(msg:Object):void {
+ // Avoid trying to reconnect
+ var endMeetingEvent:BBBEvent = new BBBEvent(BBBEvent.CANCEL_RECONNECTION_EVENT);
+ dispatcher.dispatchEvent(endMeetingEvent);
+ }
+
private function handleGetUsersReply(msg:Object):void {
var map:Object = JSON.parse(msg.msg);
var users:Object = map.users as Array;

0 comments on commit 14b480c

Please sign in to comment.