package org.bigbluebutton.red5.client;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.bigbluebutton.common.messages.BroadcastLayoutMessage;
import org.bigbluebutton.common.messages.GetCurrentLayoutReplyMessage;
import org.bigbluebutton.common.messages.GetRecordingStatusReplyMessage;
import org.bigbluebutton.common.messages.GetUsersReplyMessage;
import org.bigbluebutton.common.messages.LockLayoutMessage;
import org.bigbluebutton.common.messages.PresenterAssignedMessage;
import org.bigbluebutton.common.messages.RecordingStatusChangedMessage;
import org.bigbluebutton.common.messages.UserEmojiStatusMessage;
import org.bigbluebutton.common.messages.UserJoinedMessage;
import org.bigbluebutton.common.messages.UserJoinedVoiceMessage;
import org.bigbluebutton.common.messages.UserLeftMessage;
import org.bigbluebutton.common.messages.UserLeftVoiceMessage;
import org.bigbluebutton.common.messages.UserListeningOnlyMessage;
import org.bigbluebutton.common.messages.UserSharedWebcamMessage;
import org.bigbluebutton.common.messages.UserStatusChangedMessage;
import org.bigbluebutton.common.messages.UserUnsharedWebcamMessage;
import org.bigbluebutton.common.messages.UserVoiceMutedMessage;
import org.bigbluebutton.common.messages.UserVoiceTalkingMessage;
import org.bigbluebutton.common.messages.ValidateAuthTokenReplyMessage;
import org.bigbluebutton.common.messages.ValidateAuthTokenTimeoutMessage;
import org.bigbluebutton.common.messages.UserEjectedFromMeetingMessage;
import org.bigbluebutton.messages.BreakoutRoomClosed;
import org.bigbluebutton.messages.BreakoutRoomJoinURL;
import org.bigbluebutton.messages.BreakoutRoomStarted;
import org.bigbluebutton.messages.BreakoutRoomsList;
import org.bigbluebutton.messages.BreakoutRoomsTimeRemainingUpdate;
import org.bigbluebutton.messages.TimeRemainingUpdate;
import org.bigbluebutton.messages.UpdateBreakoutUsers;
import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage;
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class UserClientMessageSender {
private static Logger log = Red5LoggerFactory.getLogger(UserClientMessageSender.class, "bigbluebutton");
private ConnectionInvokerService service;
public UserClientMessageSender(ConnectionInvokerService service) {
this.service = service;
}
public void handleUsersMessage(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");
if (header.has("name")) {
// Used for JSON unmarshalling
Gson gson = new Gson();
String messageName = header.get("name").getAsString();
switch (messageName) {
case ValidateAuthTokenReplyMessage.VALIDATE_AUTH_TOKEN_REPLY:
ValidateAuthTokenReplyMessage m = ValidateAuthTokenReplyMessage.fromJson(message);
if (m != null) {
processValidateAuthTokenReply(m);
}
break;
case ValidateAuthTokenTimeoutMessage.VALIDATE_AUTH_TOKEN_TIMEOUT:
ValidateAuthTokenTimeoutMessage vattm = ValidateAuthTokenTimeoutMessage.fromJson(message);
if (vattm != null) {
processValidateAuthTokenTimeoutMessage(vattm);
}
break;
case UserLeftMessage.USER_LEFT:
UserLeftMessage ulm = UserLeftMessage.fromJson(message);
if (ulm != null) {
processUserLeftMessage(ulm);
}
break;
case UserJoinedMessage.USER_JOINED:
UserJoinedMessage ujm = UserJoinedMessage.fromJson(message);
if (ujm != null) {
processUserJoinedMessage(ujm);
}
break;
case PresenterAssignedMessage.PRESENTER_ASSIGNED:
PresenterAssignedMessage pam = PresenterAssignedMessage.fromJson(message);
if (pam != null) {
processPresenterAssignedMessage(pam);
}
break;
case UserStatusChangedMessage.USER_STATUS_CHANGED:
UserStatusChangedMessage usm = UserStatusChangedMessage.fromJson(message);
if (usm != null) {
processUserStatusChangedMessage(usm);
}
break;
case UserEmojiStatusMessage.USER_EMOJI_STATUS:
UserEmojiStatusMessage urhm = UserEmojiStatusMessage.fromJson(message);
if (urhm != null) {
processUserEmojiStatusMessage(urhm);
}
break;
case UserListeningOnlyMessage.USER_LISTENING_ONLY:
UserListeningOnlyMessage ulom = UserListeningOnlyMessage.fromJson(message);
if (ulom != null) {
processUserListeningOnlyMessage(ulom);
}
break;
case UserSharedWebcamMessage.USER_SHARED_WEBCAM:
UserSharedWebcamMessage uswm = UserSharedWebcamMessage.fromJson(message);
if (uswm != null) {
processUserSharedWebcamMessage(uswm);
}
break;
case UserUnsharedWebcamMessage.USER_UNSHARED_WEBCAM:
UserUnsharedWebcamMessage uuwm = UserUnsharedWebcamMessage.fromJson(message);
if (uuwm != null) {
processUserUnsharedWebcamMessage(uuwm);
}
break;
case UserJoinedVoiceMessage.USER_JOINED_VOICE:
UserJoinedVoiceMessage ujvm = UserJoinedVoiceMessage.fromJson(message);
if (ujvm != null) {
processUserJoinedVoiceMessage(ujvm);
}
break;
case UserLeftVoiceMessage.USER_LEFT_VOICE:
UserLeftVoiceMessage ulvm = UserLeftVoiceMessage.fromJson(message);
if (ulvm != null) {
processUserLeftVoiceMessage(ulvm);
}
break;
case UserVoiceMutedMessage.USER_VOICE_MUTED:
UserVoiceMutedMessage uvmm = UserVoiceMutedMessage.fromJson(message);
if (uvmm != null) {
processUserVoiceMutedMessage(uvmm);
}
break;
case UserVoiceTalkingMessage.USER_VOICE_TALKING:
UserVoiceTalkingMessage uvtm = UserVoiceTalkingMessage.fromJson(message);
if (uvtm != null) {
processUserVoiceTalkingMessage(uvtm);
}
break;
case RecordingStatusChangedMessage.RECORDING_STATUS_CHANGED:
RecordingStatusChangedMessage rscm = RecordingStatusChangedMessage.fromJson(message);
if (rscm != null) {
processRecordingStatusChangedMessage(rscm);
}
break;
case GetRecordingStatusReplyMessage.Get_RECORDING_STATUS_REPLY:
GetRecordingStatusReplyMessage grsrm = GetRecordingStatusReplyMessage.fromJson(message);
if (grsrm != null) {
processGetRecordingStatusReplyMessage(grsrm);
}
break;
case GetUsersReplyMessage.GET_USERS_REPLY:
GetUsersReplyMessage gurm = GetUsersReplyMessage.fromJson(message);
if (gurm != null) {
processGetUsersReplyMessage(gurm);
}
break;
case GetCurrentLayoutReplyMessage.GET_CURRENT_LAYOUT_REPLY:
processGetCurrentLayoutReplyMessage(message);
break;
case BroadcastLayoutMessage.BROADCAST_LAYOUT:
processBroadcastLayoutMessage(message);
break;
case LockLayoutMessage.LOCK_LAYOUT:
processLockLayoutMessage(message);
break;
case UserEjectedFromMeetingMessage.USER_EJECTED_FROM_MEETING:
processUserEjectedFromMeetingMessage(message);
break;
case BreakoutRoomsList.NAME:
BreakoutRoomsList brl = gson.fromJson(message, BreakoutRoomsList.class);
if (brl != null) {
processBreakoutRoomsList(brl);
}
break;
case BreakoutRoomJoinURL.NAME:
BreakoutRoomJoinURL brjum = gson.fromJson(message, BreakoutRoomJoinURL.class);
if (brjum != null) {
processBreakoutRoomJoinURL(brjum);
}
break;
case TimeRemainingUpdate.NAME:
TimeRemainingUpdate trum = gson.fromJson(message, TimeRemainingUpdate.class);
if (trum != null) {
processTimeRemainingUpdate(trum);
}
break;
case BreakoutRoomsTimeRemainingUpdate.NAME:
BreakoutRoomsTimeRemainingUpdate brtru = gson.fromJson(message, BreakoutRoomsTimeRemainingUpdate.class);
if (brtru != null) {
processBreakoutRoomsTimeRemainingUpdate(brtru);
}
break;
case UpdateBreakoutUsers.NAME:
UpdateBreakoutUsers ubum = gson.fromJson(message, UpdateBreakoutUsers.class);
if (ubum != null) {
processUpdateBreakoutUsers(ubum);
}
break;
case BreakoutRoomStarted.NAME:
BreakoutRoomStarted brsm = gson.fromJson(message, BreakoutRoomStarted.class);
if (brsm != null) {
processBreakoutRoomStarted(brsm);
}
break;
case BreakoutRoomClosed.NAME:
BreakoutRoomClosed brcm = gson.fromJson(message, BreakoutRoomClosed.class);
if (brcm != null) {
processBreakoutRoomClosed(brcm);
}
break;
}
}
}
}
private void processUserEjectedFromMeetingMessage(String message) {
UserEjectedFromMeetingMessage msg = UserEjectedFromMeetingMessage.fromJson(message);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("ejectedBy", msg.ejectedBy);
System.out.println("**** User [" + msg.userId + "] was ejected by [" + msg.ejectedBy + "]");
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "userEjectedFromMeeting", args);
service.sendMessage(m);
}
}
private void processLockLayoutMessage(String message) {
LockLayoutMessage msg = LockLayoutMessage.fromJson(message);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("locked", msg.locked);
args.put("setById", msg.setByUserid);
Iterator<String> usersIter = msg.users.iterator();
while (usersIter.hasNext()){
String user = usersIter.next();
DirectClientMessage m = new DirectClientMessage(msg.meetingId, user, "layoutLocked", args);
service.sendMessage(m);
}
}
}
private void processBroadcastLayoutMessage(String message) {
BroadcastLayoutMessage msg = BroadcastLayoutMessage.fromJson(message);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("locked", msg.locked);
args.put("setByUserID", msg.setByUserid);
args.put("layout", msg.layout);
Iterator<String> usersIter = msg.users.iterator();
while (usersIter.hasNext()){
String user = usersIter.next();
DirectClientMessage m = new DirectClientMessage(msg.meetingId, user, "syncLayout", args);
service.sendMessage(m);
}
}
}
private void processGetCurrentLayoutReplyMessage(String message) {
GetCurrentLayoutReplyMessage msg = GetCurrentLayoutReplyMessage.fromJson(message);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("locked", msg.locked);
args.put("setById", msg.setByUserid);
args.put("layout", msg.layout);
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requestedByUserid, "getCurrentLayoutResponse", args);
service.sendMessage(m);
}
}
private void processValidateAuthTokenReply(ValidateAuthTokenReplyMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("valid", msg.valid);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
log.info("validateAuthTokenReply - " + gson.toJson(args));
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "validateAuthTokenReply", message);
service.sendMessage(m);
}
private void processValidateAuthTokenTimeoutMessage(ValidateAuthTokenTimeoutMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("valid", msg.valid);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
log.info("validateAuthTokenTimedOut - " + gson.toJson(args));
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "validateAuthTokenTimedOut", message);
service.sendMessage(m);
}
private void processUserLeftMessage(UserLeftMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("user", msg.user);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantLeft", message);
service.sendMessage(m);
}
private void processUserJoinedMessage(UserJoinedMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("user", msg.user);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
String userId = msg.user.get("userId").toString();
log.info("joinMeetingReply - " + gson.toJson(args));
DirectClientMessage jmr = new DirectClientMessage(msg.meetingId, userId, "joinMeetingReply", message);
service.sendMessage(jmr);
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantJoined", message);
service.sendMessage(m);
}
private void processPresenterAssignedMessage(PresenterAssignedMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("newPresenterID", msg.newPresenterId);
args.put("newPresenterName", msg.newPresenterName);
args.put("assignedBy", msg.assignedBy);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "assignPresenterCallback", message);
service.sendMessage(m);
}
private void processUserEmojiStatusMessage(UserEmojiStatusMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("emojiStatus", msg.emojiStatus);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userEmojiStatus", message);
service.sendMessage(m);
}
private void processUserListeningOnlyMessage(UserListeningOnlyMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("listenOnly", msg.listenOnly);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "user_listening_only", message);
service.sendMessage(m);
}
private void processUserStatusChangedMessage(UserStatusChangedMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userID", msg.userId);
args.put("status", msg.status);
args.put("value", msg.value);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantStatusChange", message);
service.sendMessage(m);
}
private void processUserSharedWebcamMessage(UserSharedWebcamMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("webcamStream", msg.stream);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userSharedWebcam", message);
service.sendMessage(m);
}
private void processUserUnsharedWebcamMessage(UserUnsharedWebcamMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("webcamStream", msg.stream);
String timeStamp = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(Calendar.getInstance().getTime());
args.put("serverTimestamp", timeStamp );
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userUnsharedWebcam", message);
service.sendMessage(m);
}
private void processUserJoinedVoiceMessage(UserJoinedVoiceMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingID", msg.meetingId);
args.put("user", msg.user);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userJoinedVoice", message);
service.sendMessage(m);
}
private void processUserLeftVoiceMessage(UserLeftVoiceMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingID", msg.meetingId);
args.put("user", msg.user);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userLeftVoice", message);
service.sendMessage(m);
}
private void processUserVoiceMutedMessage(UserVoiceMutedMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingID", msg.meetingId);
args.put("userId", msg.user.get("userId"));
Map<String, Object> vuMap = (Map<String, Object>) msg.user.get("voiceUser");
args.put("voiceUserId", (String) vuMap.get("userId"));
args.put("muted", (Boolean) vuMap.get("muted"));
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "voiceUserMuted", message);
service.sendMessage(m);
}
private void processUserVoiceTalkingMessage(UserVoiceTalkingMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingID", msg.meetingId);
args.put("userId", msg.user.get("userId"));
Map<String, Object> vuMap = (Map<String, Object>) msg.user.get("voiceUser");
args.put("voiceUserId", (String) vuMap.get("userId"));
args.put("talking", (Boolean) vuMap.get("talking"));
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "voiceUserTalking", message);
service.sendMessage(m);
}
private void processRecordingStatusChangedMessage(RecordingStatusChangedMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("recording", msg.recording);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "recordingStatusChanged", message);
service.sendMessage(m);
}
private void processGetRecordingStatusReplyMessage(GetRecordingStatusReplyMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("userId", msg.userId);
args.put("recording", msg.recording);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "getRecordingStatusReply", message);
service.sendMessage(m);
}
private void processGetUsersReplyMessage(GetUsersReplyMessage msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("count", msg.users.size());
args.put("users", msg.users);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requesterId, "getUsersReply", message);
service.sendMessage(m);
}
private void processBreakoutRoomsList(BreakoutRoomsList msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", msg.payload.meetingId);
args.put("rooms", msg.payload.rooms);
args.put("roomsReady", msg.payload.roomsReady);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomsList", message);
service.sendMessage(m);
}
private void processBreakoutRoomJoinURL(BreakoutRoomJoinURL msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("breakoutMeetingId", msg.payload.breakoutMeetingId);
args.put("userId", msg.payload.userId);
args.put("redirectJoinURL", msg.payload.redirectJoinURL);
args.put("noRedirectJoinURL", msg.payload.noRedirectJoinURL);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
DirectClientMessage m = new DirectClientMessage(msg.payload.parentMeetingId, msg.payload.userId, "breakoutRoomJoinURL", message);
service.sendMessage(m);
}
private void processTimeRemainingUpdate(TimeRemainingUpdate msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", msg.payload.meetingId);
args.put("timeRemaining", msg.payload.timeRemaining);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "timeRemainingUpdate", message);
service.sendMessage(m);
}
private void processBreakoutRoomsTimeRemainingUpdate(BreakoutRoomsTimeRemainingUpdate msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", msg.payload.meetingId);
args.put("timeRemaining", msg.payload.timeRemaining);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomsTimeRemainingUpdate", message);
service.sendMessage(m);
}
private void processUpdateBreakoutUsers(UpdateBreakoutUsers msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("breakoutMeetingId", msg.payload.breakoutMeetingId);
args.put("users", msg.payload.users);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "updateBreakoutUsers", message);
service.sendMessage(m);
}
private void processBreakoutRoomStarted(BreakoutRoomStarted msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("breakoutMeetingId", msg.payload.meetingId);
args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("externalMeetingId", msg.payload.externalMeetingId);
args.put("sequence", msg.payload.sequence);
args.put("name", msg.payload.name);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomStarted", message);
service.sendMessage(m);
}
private void processBreakoutRoomClosed(BreakoutRoomClosed msg) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("breakoutMeetingId", msg.payload.meetingId);
args.put("parentMeetingId", msg.payload.parentMeetingId);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomClosed", message);
service.sendMessage(m);
}
}