From f4d094adc0b29fc158889efdc352cd49f2820e63 Mon Sep 17 00:00:00 2001 From: Richard Alam Date: Thu, 8 Oct 2015 18:26:22 +0000 Subject: [PATCH 1/4] - allow changing the debug level without restarting red5 --- .../src/main/resources/logback-bigbluebutton.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-apps/src/main/resources/logback-bigbluebutton.xml b/bigbluebutton-apps/src/main/resources/logback-bigbluebutton.xml index 134933a0d3..1e8bc71075 100755 --- a/bigbluebutton-apps/src/main/resources/logback-bigbluebutton.xml +++ b/bigbluebutton-apps/src/main/resources/logback-bigbluebutton.xml @@ -18,7 +18,9 @@ You should have received a copy of the GNU Lesser General Public License along with BigBlueButton; if not, see . --> - + + + log/bigbluebutton.log From e5ed0e47130f6df458416c0c177feb27538c67cd Mon Sep 17 00:00:00 2001 From: Richard Alam Date: Thu, 8 Oct 2015 18:27:33 +0000 Subject: [PATCH 2/4] - add logging to trace messages in order to debug lost messages between server to client --- .../messaging/ConnectionInvokerService.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java index 69e50e5f83..8c1cea7d7e 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java @@ -38,6 +38,8 @@ import org.red5.server.so.SharedObjectService; import org.red5.server.util.ScopeUtils; import org.slf4j.Logger; +import com.google.gson.Gson; + public class ConnectionInvokerService { private static Logger log = Red5LoggerFactory.getLogger(ConnectionInvokerService.class, "bigbluebutton"); @@ -162,6 +164,12 @@ public class ConnectionInvokerService { } private void sendDirectMessage(final DirectClientMessage msg) { + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Handle direct message: " + msg.getMessageName() + " msg=" + json); + } + final String sessionId = CONN + msg.getUserID(); Runnable sender = new Runnable() { public void run() { @@ -174,6 +182,11 @@ public class ConnectionInvokerService { List params = new ArrayList(); params.add(msg.getMessageName()); params.add(msg.getMessage()); + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Send direct message: " + msg.getMessageName() + " msg=" + json); + } ServiceUtils.invokeOnConnection(conn, "onMessageFromServer", params.toArray()); } } else { @@ -187,6 +200,12 @@ public class ConnectionInvokerService { } private void sendBroadcastMessage(final BroadcastClientMessage msg) { + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Handle broadcast message: " + msg.getMessageName() + " msg=" + json); + } + Runnable sender = new Runnable() { public void run() { IScope meetingScope = getScope(msg.getMeetingID()); @@ -194,6 +213,11 @@ public class ConnectionInvokerService { List params = new ArrayList(); params.add(msg.getMessageName()); params.add(msg.getMessage()); + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Broadcast message: " + msg.getMessageName() + " msg=" + json); + } ServiceUtils.invokeOnAllScopeConnections(meetingScope, "onMessageFromServer", params.toArray(), null); } } @@ -209,7 +233,7 @@ public class ConnectionInvokerService { return conn; } } - + log.warn("Failed to get connection for userId = " + userID); return null; } From 197669ebc41d6f98b0c1db05c072603632741c62 Mon Sep 17 00:00:00 2001 From: Richard Alam Date: Thu, 8 Oct 2015 18:28:25 +0000 Subject: [PATCH 3/4] - add a timeout when to expect response to validate token. If we don't get a response, log it. This might mean that we run into issue where the reply from server isn't getting propagated back into the client. --- .../main/model/users/NetConnectionDelegate.as | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as index 5fde55a545..ab6265b6e1 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as @@ -31,7 +31,6 @@ package org.bigbluebutton.main.model.users import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.getClassLogger; - import org.as3commons.logging.util.jsonXify; import org.bigbluebutton.core.UsersUtil; import org.bigbluebutton.core.managers.ReconnectionManager; import org.bigbluebutton.core.services.BandwidthMonitor; @@ -70,6 +69,8 @@ package org.bigbluebutton.main.model.users private var reconnecting:Boolean = false; private var numNetworkChangeCount:int = 0; + private var _validateTokenTimer:Timer = null; + public function NetConnectionDelegate():void { dispatcher = new Dispatcher(); @@ -126,12 +127,24 @@ package org.bigbluebutton.main.model.users LOGGER.debug("Ignoring message=[{0}] as our token hasn't been validated yet.", [messageName]); } } - + + private function validataTokenTimerHandler(event:TimerEvent):void { + var logData:Object = new Object(); + logData.user = UsersUtil.getUserData(); + JSLog.critical("No response for validate token request.", logData); + logData.message = "No response for validate token request."; + LOGGER.info(JSON.stringify(logData)); + } + private function validateToken():void { var message:Object = new Object(); message["userId"] = _conferenceParameters.internalUserID; message["authToken"] = _conferenceParameters.authToken; + _validateTokenTimer = new Timer(7000, 1); + _validateTokenTimer.addEventListener(TimerEvent.TIMER, validataTokenTimerHandler); + _validateTokenTimer.start(); + sendMessage( "validateToken",// Remote function name // result - On successful result @@ -148,8 +161,17 @@ package org.bigbluebutton.main.model.users message ); //_netConnection.call } - + + private function stopValidateTokenTimer():void { + if (_validateTokenTimer != null && _validateTokenTimer.running) { + _validateTokenTimer.stop(); + _validateTokenTimer = null; + } + } + private function handleValidateAuthTokenTimedOut(msg: Object):void { + stopValidateTokenTimer(); + var map:Object = JSON.parse(msg.msg); var tokenValid: Boolean = map.valid as Boolean; var userId: String = map.userId as String; @@ -172,7 +194,9 @@ package org.bigbluebutton.main.model.users } } - private function handleValidateAuthTokenReply(msg: Object):void { + private function handleValidateAuthTokenReply(msg: Object):void { + stopValidateTokenTimer(); + var map:Object = JSON.parse(msg.msg); var tokenValid: Boolean = map.valid as Boolean; var userId: String = map.userId as String; From e8e8eb89555aedf7d80969aa0c18b49c1e1b6bc2 Mon Sep 17 00:00:00 2001 From: Richard Alam Date: Thu, 8 Oct 2015 19:10:43 +0000 Subject: [PATCH 4/4] - clean up formatting --- .../red5/client/UserClientMessageSender.java | 833 +++++++++--------- .../messaging/ConnectionInvokerService.java | 405 +++++---- 2 files changed, 615 insertions(+), 623 deletions(-) diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java index 042461e81a..2d7a86f822 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/UserClientMessageSender.java @@ -37,428 +37,425 @@ 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"); + private static Logger log = Red5LoggerFactory.getLogger(UserClientMessageSender.class, "bigbluebutton"); - if (header.has("name")) { - 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; - } - } - } - } + private ConnectionInvokerService service; - private void processLockLayoutMessage(String message) { - LockLayoutMessage msg = LockLayoutMessage.fromJson(message); - if (msg != null) { - Map args = new HashMap(); - args.put("locked", msg.locked); - args.put("setById", msg.setByUserid); - - Iterator 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 args = new HashMap(); - args.put("locked", msg.locked); - args.put("setByUserID", msg.setByUserid); - args.put("layout", msg.layout); - - Iterator 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 args = new HashMap(); - 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 args = new HashMap(); - args.put("userId", msg.userId); - args.put("valid", msg.valid); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("userId", msg.userId); - args.put("valid", msg.valid); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("user", msg.user); - - Map message = new HashMap(); - Gson gson = new Gson(); - message.put("msg", gson.toJson(args)); - - BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantLeft", message); - service.sendMessage(m); - } + public UserClientMessageSender(ConnectionInvokerService service) { + this.service = service; + } - private void processUserJoinedMessage(UserJoinedMessage msg) { - Map args = new HashMap(); - args.put("user", msg.user); - - Map message = new HashMap(); - 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); - } + 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"); - private void processPresenterAssignedMessage(PresenterAssignedMessage msg) { - Map args = new HashMap(); - args.put("newPresenterID", msg.newPresenterId); - args.put("newPresenterName", msg.newPresenterName); - args.put("assignedBy", msg.assignedBy); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("userId", msg.userId); - args.put("emojiStatus", msg.emojiStatus); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("userId", msg.userId); - args.put("listenOnly", msg.listenOnly); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("userID", msg.userId); - args.put("status", msg.status); - args.put("value", msg.value); - - Map message = new HashMap(); - Gson gson = new Gson(); - message.put("msg", gson.toJson(args)); - - BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantStatusChange", message); - service.sendMessage(m); - } + if (header.has("name")) { + 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; + } + } + } + } - private void processUserSharedWebcamMessage(UserSharedWebcamMessage msg) { - Map args = new HashMap(); - args.put("userId", msg.userId); - args.put("webcamStream", msg.stream); - - Map message = new HashMap(); - 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 args = new HashMap(); - 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 message = new HashMap(); - 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 args = new HashMap(); - args.put("meetingID", msg.meetingId); - args.put("user", msg.user); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("meetingID", msg.meetingId); - args.put("user", msg.user); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("meetingID", msg.meetingId); - args.put("userId", msg.user.get("userId")); - - Map vuMap = (Map) msg.user.get("voiceUser"); - - args.put("voiceUserId", (String) vuMap.get("userId")); - args.put("muted", (Boolean) vuMap.get("muted")); - - Map message = new HashMap(); - Gson gson = new Gson(); - message.put("msg", gson.toJson(args)); - - BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "voiceUserMuted", message); - service.sendMessage(m); - } + private void processLockLayoutMessage(String message) { + LockLayoutMessage msg = LockLayoutMessage.fromJson(message); + if (msg != null) { + Map args = new HashMap(); + args.put("locked", msg.locked); + args.put("setById", msg.setByUserid); + + Iterator 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 processUserVoiceTalkingMessage(UserVoiceTalkingMessage msg) { - Map args = new HashMap(); - args.put("meetingID", msg.meetingId); - args.put("userId", msg.user.get("userId")); - - Map vuMap = (Map) msg.user.get("voiceUser"); - - args.put("voiceUserId", (String) vuMap.get("userId")); - args.put("talking", (Boolean) vuMap.get("talking")); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("userId", msg.userId); - args.put("recording", msg.recording); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("userId", msg.userId); - args.put("recording", msg.recording); - - Map message = new HashMap(); - 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 args = new HashMap(); - args.put("count", msg.users.size()); - args.put("users", msg.users); - - Map message = new HashMap(); - 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 processBroadcastLayoutMessage(String message) { + BroadcastLayoutMessage msg = BroadcastLayoutMessage.fromJson(message); + if (msg != null) { + Map args = new HashMap(); + args.put("locked", msg.locked); + args.put("setByUserID", msg.setByUserid); + args.put("layout", msg.layout); + + Iterator 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 args = new HashMap(); + 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 args = new HashMap(); + args.put("userId", msg.userId); + args.put("valid", msg.valid); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("userId", msg.userId); + args.put("valid", msg.valid); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("user", msg.user); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("user", msg.user); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("newPresenterID", msg.newPresenterId); + args.put("newPresenterName", msg.newPresenterName); + args.put("assignedBy", msg.assignedBy); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("userId", msg.userId); + args.put("emojiStatus", msg.emojiStatus); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("userId", msg.userId); + args.put("listenOnly", msg.listenOnly); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("userID", msg.userId); + args.put("status", msg.status); + args.put("value", msg.value); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("userId", msg.userId); + args.put("webcamStream", msg.stream); + + Map message = new HashMap(); + 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 args = new HashMap(); + 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 message = new HashMap(); + 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 args = new HashMap(); + args.put("meetingID", msg.meetingId); + args.put("user", msg.user); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("meetingID", msg.meetingId); + args.put("user", msg.user); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("meetingID", msg.meetingId); + args.put("userId", msg.user.get("userId")); + + Map vuMap = (Map) msg.user.get("voiceUser"); + + args.put("voiceUserId", (String) vuMap.get("userId")); + args.put("muted", (Boolean) vuMap.get("muted")); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("meetingID", msg.meetingId); + args.put("userId", msg.user.get("userId")); + + Map vuMap = (Map) msg.user.get("voiceUser"); + + args.put("voiceUserId", (String) vuMap.get("userId")); + args.put("talking", (Boolean) vuMap.get("talking")); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("userId", msg.userId); + args.put("recording", msg.recording); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("userId", msg.userId); + args.put("recording", msg.recording); + + Map message = new HashMap(); + 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 args = new HashMap(); + args.put("count", msg.users.size()); + args.put("users", msg.users); + + Map message = new HashMap(); + Gson gson = new Gson(); + message.put("msg", gson.toJson(args)); + + DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requesterId, "getUsersReply", message); + service.sendMessage(m); + } } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java index 8c1cea7d7e..f7045ee8d3 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/messaging/ConnectionInvokerService.java @@ -26,7 +26,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; - import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.IConnection; import org.red5.server.api.scope.IScope; @@ -37,218 +36,214 @@ import org.red5.server.api.so.ISharedObjectService; import org.red5.server.so.SharedObjectService; import org.red5.server.util.ScopeUtils; import org.slf4j.Logger; - import com.google.gson.Gson; public class ConnectionInvokerService { - private static Logger log = Red5LoggerFactory.getLogger(ConnectionInvokerService.class, "bigbluebutton"); - - private final String CONN = "RED5-"; - - private static final int NTHREADS = 1; - private static final Executor exec = Executors.newFixedThreadPool(NTHREADS); - private static final Executor runExec = Executors.newFixedThreadPool(NTHREADS); - - private BlockingQueue messages; - - private volatile boolean sendMessages = false; - private IScope bbbAppScope; + private static Logger log = Red5LoggerFactory.getLogger(ConnectionInvokerService.class, "bigbluebutton"); - public ConnectionInvokerService() { - messages = new LinkedBlockingQueue(); - } + private final String CONN = "RED5-"; + private static final int NTHREADS = 1; + private static final Executor exec = Executors.newFixedThreadPool(NTHREADS); + private static final Executor runExec = Executors.newFixedThreadPool(NTHREADS); - public void setAppScope(IScope scope) { - bbbAppScope = scope; - } + private BlockingQueue messages; + private volatile boolean sendMessages = false; + private IScope bbbAppScope; - public void start() { - sendMessages = true; - Runnable sender = new Runnable() { - public void run() { - while (sendMessages) { - ClientMessage message; - try { - message = messages.take(); - sendMessageToClient(message); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - } - }; - exec.execute(sender); - } - - public void stop() { - sendMessages = false; - } - - public void sendMessage(final ClientMessage message) { - messages.offer(message); - } - - private void sendMessageToClient(ClientMessage message) { - if (message instanceof BroadcastClientMessage) { - sendBroadcastMessage((BroadcastClientMessage) message); - } else if (message instanceof DirectClientMessage) { - sendDirectMessage((DirectClientMessage) message); - } else if (message instanceof SharedObjectClientMessage) { - sendSharedObjectMessage((SharedObjectClientMessage) message); - } else if (message instanceof DisconnectClientMessage) { - handlDisconnectClientMessage((DisconnectClientMessage) message); - } else if (message instanceof DisconnectAllClientsMessage) { - handleDisconnectAllClientsMessage((DisconnectAllClientsMessage) message); - } else if (message instanceof DisconnectAllMessage) { - handleDisconnectAllMessage((DisconnectAllMessage) message); - } - } + public ConnectionInvokerService() { + messages = new LinkedBlockingQueue(); + } - private void handleDisconnectAllMessage(DisconnectAllMessage msg) { - IScope meetingScope = bbbAppScope.getContext().resolveScope("bigbluebutton"); - - if (meetingScope != null) { - Set conns = meetingScope.getClientConnections(); + public void setAppScope(IScope scope) { + bbbAppScope = scope; + } - for (IConnection conn : conns) { - if (conn.isConnected()) { - String connId = (String) conn.getAttribute("INTERNAL_USER_ID"); - log.info("Disconnecting client=[{}] as bbb-apps isn't running.", connId); - conn.close(); - } - } - } - } - - private void handleDisconnectAllClientsMessage(DisconnectAllClientsMessage msg) { - IScope meetingScope = getScope(msg.getMeetingId()); - if (meetingScope != null) { - Set conns = meetingScope.getClientConnections(); - - for (IConnection conn : conns) { - if (conn.isConnected()) { - String connId = (String) conn.getAttribute("INTERNAL_USER_ID"); - log.info("Disconnecting client=[{}] from meeting=[{}]", connId, msg.getMeetingId()); - conn.close(); - } - } - } - } - - private void handlDisconnectClientMessage(DisconnectClientMessage msg) { - IScope meetingScope = getScope(msg.getMeetingId()); - if (meetingScope != null) { - String sessionId = CONN + msg.getUserId(); - IConnection conn = getConnection(meetingScope, sessionId); - if (conn != null) { - if (conn.isConnected()) { - log.info("Disconnecting user=[{}] from meeting=[{}]", msg.getUserId(), msg.getMeetingId()); - conn.close(); - } - } - } - } - - private void sendSharedObjectMessage(SharedObjectClientMessage msg) { - IScope meetingScope = getScope(msg.getMeetingID()); - if (meetingScope != null) { - if (meetingScope.hasChildScope(ScopeType.SHARED_OBJECT, msg.getSharedObjectName())) { - ISharedObject so = getSharedObject(meetingScope, msg.getSharedObjectName()); - if (so != null) { - so.sendMessage(msg.getMessageName(), msg.getMessage()); - } - } - } - } - - private void sendDirectMessage(final DirectClientMessage msg) { - if (log.isTraceEnabled()) { - Gson gson = new Gson(); - String json = gson.toJson(msg.getMessage()); - log.trace("Handle direct message: " + msg.getMessageName() + " msg=" + json); + public void start() { + sendMessages = true; + Runnable sender = new Runnable() { + public void run() { + while (sendMessages) { + ClientMessage message; + try { + message = messages.take(); + sendMessageToClient(message); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } - - final String sessionId = CONN + msg.getUserID(); - Runnable sender = new Runnable() { - public void run() { - IScope meetingScope = getScope(msg.getMeetingID()); - if (meetingScope != null) { - - IConnection conn = getConnection(meetingScope, sessionId); - if (conn != null) { - if (conn.isConnected()) { - List params = new ArrayList(); - params.add(msg.getMessageName()); - params.add(msg.getMessage()); - if (log.isTraceEnabled()) { - Gson gson = new Gson(); - String json = gson.toJson(msg.getMessage()); - log.trace("Send direct message: " + msg.getMessageName() + " msg=" + json); - } - ServiceUtils.invokeOnConnection(conn, "onMessageFromServer", params.toArray()); - } - } else { - log.info("Cannot send message=[" + msg.getMessageName() + "] to [" + sessionId - + "] as no such session on meeting=[" + msg.getMeetingID() + "]"); - } - } - } - }; - runExec.execute(sender); - } - - private void sendBroadcastMessage(final BroadcastClientMessage msg) { - if (log.isTraceEnabled()) { - Gson gson = new Gson(); - String json = gson.toJson(msg.getMessage()); - log.trace("Handle broadcast message: " + msg.getMessageName() + " msg=" + json); + }; + exec.execute(sender); + } + + public void stop() { + sendMessages = false; + } + + public void sendMessage(final ClientMessage message) { + messages.offer(message); + } + + private void sendMessageToClient(ClientMessage message) { + if (message instanceof BroadcastClientMessage) { + sendBroadcastMessage((BroadcastClientMessage) message); + } else if (message instanceof DirectClientMessage) { + sendDirectMessage((DirectClientMessage) message); + } else if (message instanceof SharedObjectClientMessage) { + sendSharedObjectMessage((SharedObjectClientMessage) message); + } else if (message instanceof DisconnectClientMessage) { + handlDisconnectClientMessage((DisconnectClientMessage) message); + } else if (message instanceof DisconnectAllClientsMessage) { + handleDisconnectAllClientsMessage((DisconnectAllClientsMessage) message); + } else if (message instanceof DisconnectAllMessage) { + handleDisconnectAllMessage((DisconnectAllMessage) message); + } + } + + private void handleDisconnectAllMessage(DisconnectAllMessage msg) { + IScope meetingScope = bbbAppScope.getContext().resolveScope("bigbluebutton"); + + if (meetingScope != null) { + Set conns = meetingScope.getClientConnections(); + + for (IConnection conn : conns) { + if (conn.isConnected()) { + String connId = (String) conn.getAttribute("INTERNAL_USER_ID"); + log.info("Disconnecting client=[{}] as bbb-apps isn't running.", connId); + conn.close(); + } + } + } + } + + private void handleDisconnectAllClientsMessage(DisconnectAllClientsMessage msg) { + IScope meetingScope = getScope(msg.getMeetingId()); + if (meetingScope != null) { + Set conns = meetingScope.getClientConnections(); + + for (IConnection conn : conns) { + if (conn.isConnected()) { + String connId = (String) conn.getAttribute("INTERNAL_USER_ID"); + log.info("Disconnecting client=[{}] from meeting=[{}]", connId, msg.getMeetingId()); + conn.close(); + } + } + } + } + + private void handlDisconnectClientMessage(DisconnectClientMessage msg) { + IScope meetingScope = getScope(msg.getMeetingId()); + if (meetingScope != null) { + String sessionId = CONN + msg.getUserId(); + IConnection conn = getConnection(meetingScope, sessionId); + if (conn != null) { + if (conn.isConnected()) { + log.info("Disconnecting user=[{}] from meeting=[{}]", msg.getUserId(), msg.getMeetingId()); + conn.close(); + } + } + } + } + + private void sendSharedObjectMessage(SharedObjectClientMessage msg) { + IScope meetingScope = getScope(msg.getMeetingID()); + if (meetingScope != null) { + if (meetingScope.hasChildScope(ScopeType.SHARED_OBJECT, msg.getSharedObjectName())) { + ISharedObject so = getSharedObject(meetingScope, msg.getSharedObjectName()); + if (so != null) { + so.sendMessage(msg.getMessageName(), msg.getMessage()); + } + } + } + } + + private void sendDirectMessage(final DirectClientMessage msg) { + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Handle direct message: " + msg.getMessageName() + " msg=" + json); + } + + final String sessionId = CONN + msg.getUserID(); + Runnable sender = new Runnable() { + public void run() { + IScope meetingScope = getScope(msg.getMeetingID()); + if (meetingScope != null) { + + IConnection conn = getConnection(meetingScope, sessionId); + if (conn != null) { + if (conn.isConnected()) { + List params = new ArrayList(); + params.add(msg.getMessageName()); + params.add(msg.getMessage()); + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Send direct message: " + msg.getMessageName() + " msg=" + json); + } + ServiceUtils.invokeOnConnection(conn, "onMessageFromServer", params.toArray()); + } + } else { + log.info("Cannot send message=[" + msg.getMessageName() + "] to [" + sessionId + + "] as no such session on meeting=[" + msg.getMeetingID() + "]"); + } + } } - - Runnable sender = new Runnable() { - public void run() { - IScope meetingScope = getScope(msg.getMeetingID()); - if (meetingScope != null) { - List params = new ArrayList(); - params.add(msg.getMessageName()); - params.add(msg.getMessage()); - if (log.isTraceEnabled()) { - Gson gson = new Gson(); - String json = gson.toJson(msg.getMessage()); - log.trace("Broadcast message: " + msg.getMessageName() + " msg=" + json); - } - ServiceUtils.invokeOnAllScopeConnections(meetingScope, "onMessageFromServer", params.toArray(), null); - } - } - }; - runExec.execute(sender); - } - - private IConnection getConnection(IScope scope, String userID) { - Set conns = scope.getClientConnections(); - for (IConnection conn : conns) { - String connID = (String) conn.getAttribute("USER_SESSION_ID"); - if (connID != null && connID.equals(userID)) { - return conn; - } - } - log.warn("Failed to get connection for userId = " + userID); - return null; - } - - public IScope getScope(String meetingID) { - if (bbbAppScope != null) { - return bbbAppScope.getContext().resolveScope("bigbluebutton/" + meetingID); - } else { - log.error("BigBlueButton Scope not initialized. No messages are going to the Flash client!"); - } - - return null; - } - - private ISharedObject getSharedObject(IScope scope, String name) { - ISharedObjectService service = (ISharedObjectService) ScopeUtils.getScopeService(scope, ISharedObjectService.class, SharedObjectService.class, false); - return service.getSharedObject(scope, name); - } + }; + runExec.execute(sender); + } + + private void sendBroadcastMessage(final BroadcastClientMessage msg) { + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Handle broadcast message: " + msg.getMessageName() + " msg=" + json); + } + + Runnable sender = new Runnable() { + public void run() { + IScope meetingScope = getScope(msg.getMeetingID()); + if (meetingScope != null) { + List params = new ArrayList(); + params.add(msg.getMessageName()); + params.add(msg.getMessage()); + if (log.isTraceEnabled()) { + Gson gson = new Gson(); + String json = gson.toJson(msg.getMessage()); + log.trace("Broadcast message: " + msg.getMessageName() + " msg=" + json); + } + ServiceUtils.invokeOnAllScopeConnections(meetingScope, "onMessageFromServer", params.toArray(), null); + } + } + }; + runExec.execute(sender); + } + + private IConnection getConnection(IScope scope, String userID) { + Set conns = scope.getClientConnections(); + for (IConnection conn : conns) { + String connID = (String) conn.getAttribute("USER_SESSION_ID"); + if (connID != null && connID.equals(userID)) { + return conn; + } + } + log.warn("Failed to get connection for userId = " + userID); + return null; + } + + public IScope getScope(String meetingID) { + if (bbbAppScope != null) { + return bbbAppScope.getContext().resolveScope("bigbluebutton/" + meetingID); + } else { + log.error("BigBlueButton Scope not initialized. No messages are going to the Flash client!"); + } + + return null; + } + + private ISharedObject getSharedObject(IScope scope, String name) { + ISharedObjectService service = (ISharedObjectService) ScopeUtils.getScopeService(scope, ISharedObjectService.class, SharedObjectService.class, false); + return service.getSharedObject(scope, name); + } }