diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ClientToServerLatencyTracerMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ClientToServerLatencyTracerMsgHdlr.scala new file mode 100755 index 0000000000..f5b003c20b --- /dev/null +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/whiteboard/ClientToServerLatencyTracerMsgHdlr.scala @@ -0,0 +1,26 @@ +package org.bigbluebutton.core.apps.whiteboard + +import org.bigbluebutton.common2.msgs._ +import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter } + +trait ClientToServerLatencyTracerMsgHdlr { + this: MeetingActor => + + val outGW: OutMsgRouter + + def handleClientToServerLatencyTracerMsg(msg: ClientToServerLatencyTracerMsg): Unit = { + + def broadcastEvent(): Unit = { + val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, props.meetingProp.intId, msg.header.userId) + val envelope = BbbCoreEnvelope(ServerToClientLatencyTracerMsg.NAME, routing) + val header = BbbClientMsgHeader(ServerToClientLatencyTracerMsg.NAME, props.meetingProp.intId, msg.header.userId) + + val body = ServerToClientLatencyTracerMsgBody(msg.body.timestamp, msg.body.prettyTimestamp, msg.body.tzOffset, msg.body.senderId) + val event = ServerToClientLatencyTracerMsg(header, body) + val msgEvent = BbbCommonEnvCoreMsg(envelope, event) + outGW.send(msgEvent) + } + + broadcastEvent() + } +} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala index 6f0872b82d..a186edd71a 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala @@ -166,6 +166,9 @@ class ReceivedJsonMsgHandlerActor( routeGenericMsg[SendWhiteboardAnnotationPubMsg](envelope, jsonNode) case GetWhiteboardAnnotationsReqMsg.NAME => routeGenericMsg[GetWhiteboardAnnotationsReqMsg](envelope, jsonNode) + case ClientToServerLatencyTracerMsg.NAME => + log.info("-- trace --" + jsonNode.toString) + routeGenericMsg[ClientToServerLatencyTracerMsg](envelope, jsonNode) // Presentation case SetCurrentPresentationPubMsg.NAME => diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index 965d16d973..f46f6fd0ab 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -3,6 +3,7 @@ package org.bigbluebutton.core.running import java.io.{ PrintWriter, StringWriter } import org.bigbluebutton.core.apps.users._ +import org.bigbluebutton.core.apps.whiteboard.ClientToServerLatencyTracerMsgHdlr import org.bigbluebutton.core.domain.{ MeetingExpiryTracker, MeetingInactivityTracker, MeetingState2x } import org.bigbluebutton.core.util.TimeUtil //import java.util.concurrent.TimeUnit @@ -78,7 +79,8 @@ class MeetingActor( with SendTimeRemainingUpdateHdlr with SendBreakoutTimeRemainingMsgHdlr with ChangeLockSettingsInMeetingCmdMsgHdlr - with SyncGetMeetingInfoRespMsgHdlr { + with SyncGetMeetingInfoRespMsgHdlr + with ClientToServerLatencyTracerMsgHdlr { override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) { case e: Exception => { @@ -207,6 +209,7 @@ class MeetingActor( case m: GetWhiteboardAccessReqMsg => handleGetWhiteboardAccessReqMsg(m) case m: SendWhiteboardAnnotationPubMsg => handleSendWhiteboardAnnotationPubMsg(m) case m: GetWhiteboardAnnotationsReqMsg => handleGetWhiteboardAnnotationsReqMsg(m) + case m: ClientToServerLatencyTracerMsg => handleClientToServerLatencyTracerMsg(m) // Poll case m: StartPollReqMsg => handleStartPollReqMsg(m) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala index b85302102e..897a863e49 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala @@ -22,6 +22,11 @@ class AnalyticsActor extends Actor with ActorLogging { log.info(TAG + json) } + def traceMessage(msg: BbbCommonEnvCoreMsg): Unit = { + val json = JsonUtil.toJson(msg) + log.info(" -- trace -- " + json) + } + def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = { msg.core match { @@ -76,6 +81,9 @@ class AnalyticsActor extends Actor with ActorLogging { case m: SetCurrentPresentationPubMsg => logMessage(msg) case m: SetCurrentPresentationEvtMsg => logMessage(msg) + case m: ClientToServerLatencyTracerMsg => traceMessage(msg) + case m: ServerToClientLatencyTracerMsg => traceMessage(msg) + case _ => // ignore message } } diff --git a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala index 8b0b318d1c..10ce7a3d5a 100755 --- a/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala +++ b/bbb-apps-common/src/main/scala/org/bigbluebutton/client/meeting/UserActor.scala @@ -79,7 +79,7 @@ class UserActor(val userId: String, def handleMsgFromClientMsg(msg: MsgFromClientMsg):Unit = { - log.debug("Received MsgFromClientMsg " + msg) + def convertToJsonNode(json: String): Option[JsonNode] = { JsonUtil.toJsonNode(json) match { @@ -97,6 +97,10 @@ class UserActor(val userId: String, val routing = Routing.addMsgFromClientRouting(msgFromClient.header.meetingId, msgFromClient.header.userId) val envelope = new BbbCoreEnvelope(msgFromClient.header.name, routing) + if (msgFromClient.header.name == "ClientToServerLatencyTracerMsg") { + log.info("-- trace -- " + msg.json) + } + for { jsonNode <- convertToJsonNode(msg.json) } yield { diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WhiteboardMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WhiteboardMsgs.scala index 3fd6fa77a7..308bbae399 100755 --- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WhiteboardMsgs.scala +++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WhiteboardMsgs.scala @@ -3,6 +3,15 @@ package org.bigbluebutton.common2.msgs case class AnnotationVO(id: String, status: String, annotationType: String, annotationInfo: scala.collection.immutable.Map[String, Any], wbId: String, userId: String, position: Int) +object ClientToServerLatencyTracerMsg { val NAME = "ClientToServerLatencyTracerMsg" } +case class ClientToServerLatencyTracerMsg(header: BbbClientMsgHeader, body: ClientToServerLatencyTracerMsgBody) extends StandardMsg +case class ClientToServerLatencyTracerMsgBody(timestamp: Long, prettyTimestamp: String, tzOffset: Long, senderId: String) + +object ServerToClientLatencyTracerMsg { val NAME = "ServerToClientLatencyTracerMsg" } +case class ServerToClientLatencyTracerMsg(header: BbbClientMsgHeader, body: ServerToClientLatencyTracerMsgBody) extends BbbCoreMsg +case class ServerToClientLatencyTracerMsgBody(timestamp: Long, prettyTimestamp: String, tzOffset: Long, senderId: String) + + object ClearWhiteboardEvtMsg { val NAME = "ClearWhiteboardEvtMsg" } 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 456390ea16..0372c97a48 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 @@ -58,7 +58,9 @@ public class ConnectionInvokerService implements IConnectionInvokerService { private IScope bbbAppScope; private final long SEND_TIMEOUT = 5000000000L; // 5s - + + private Long lastMsgLengthLog = System.currentTimeMillis(); + public ConnectionInvokerService() { messages = new LinkedBlockingQueue(); } @@ -74,6 +76,10 @@ public class ConnectionInvokerService implements IConnectionInvokerService { while (sendMessages) { ClientMessage message; try { + if (System.currentTimeMillis() - lastMsgLengthLog > 60000) { + lastMsgLengthLog = System.currentTimeMillis(); + log.info("Message queue length = " + messages.size()); + } message = messages.take(); if (log.isTraceEnabled()) { log.trace("Took message from queue: " + message.getMessageName()); @@ -169,6 +175,10 @@ public class ConnectionInvokerService implements IConnectionInvokerService { log.trace("Handle direct message: " + msg.messageName + " msg=" + msg.json); } + if ("ServerToClientLatencyTracerMsg".equals(msg.messageName)) { + log.info("-- trace -- " + msg.json); + } + final String connId = msg.connId; Runnable sender = new Runnable() { public void run() { diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/events/RoundTripLatencyReceivedEvent.as b/bigbluebutton-client/src/org/bigbluebutton/core/events/RoundTripLatencyReceivedEvent.as new file mode 100755 index 0000000000..458d64f310 --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/core/events/RoundTripLatencyReceivedEvent.as @@ -0,0 +1,14 @@ +package org.bigbluebutton.core.events +{ + import flash.events.Event; + + public class RoundTripLatencyReceivedEvent extends Event + { + public static const ROUND_TRIP_LATENCY_RECEIVED: String = "round trip latency received event"; + + public function RoundTripLatencyReceivedEvent() + { + super(ROUND_TRIP_LATENCY_RECEIVED, false, false); + } + } +} \ No newline at end of file diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml index c5ea525ea4..9bb22054cf 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml @@ -82,73 +82,77 @@ with BigBlueButton; if not, see . + + . PopUpUtil.createModalPopUp(mdiCanvas, AudioSelectionWindow, true); } + private function handleRoundTripLatencyReceivedEvent(event: RoundTripLatencyReceivedEvent): void { + rttLabel.text = "RTT = " + LiveMeeting.inst().whiteboardModel.latencyInSec + "s"; + } + private function handleWebRTCMediaRequestEvent(event:WebRTCMediaEvent):void { var options:PhoneOptions = new PhoneOptions(); if (!options.showMicrophoneHint) return; @@ -1052,6 +1060,11 @@ with BigBlueButton; if not, see . id="copyrightLabel2" truncateToFit="true" selectable="true" paddingRight="10"/> + 60000) { + var prettyDate: String = now.toString(); + var ts: Number = now.time; + var tzOffset: Number = now.timezoneOffset; + + LiveMeeting.inst().whiteboardModel.sentLastTrace(now); + + var message:Object = { + header: {name: "ClientToServerLatencyTracerMsg", meetingId: UsersUtil.getInternalMeetingID(), userId: UsersUtil.getMyUserID()}, + body: {timestamp: ts, prettyTimestamp: prettyDate, tzOffset: tzOffset, senderId: UsersUtil.getMyUserID()} + }; + + var _nc:ConnectionManager = BBB.initConnectionManager(); + _nc.sendMessage2x( + function(result:String):void { // On successful result + //LOGGER.debug(result); + }, + function(status:String):void { // status - On error occurred + //LOGGER.error(status); + }, + JSON.stringify(message) + ); + } + } + } }