diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java index d5562595647c8e667561507bed7284bc40f206ea..ce1c25bb2329733c64c0dad0034ac1260f29e624 100755 --- a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java +++ b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java @@ -79,6 +79,9 @@ public class VideoApplication extends MultiThreadedApplicationAdapter { for (IConnection conn : conns) { String connUserId = (String) conn.getAttribute("USERID"); String connSessionId = conn.getSessionId(); + String clientId = conn.getClient().getId(); + String remoteHost = conn.getRemoteAddress(); + int remotePort = conn.getRemotePort(); if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) { conn.removeAttribute("USERID"); Map<String, Object> logData = new HashMap<String, Object>(); @@ -86,6 +89,8 @@ public class VideoApplication extends MultiThreadedApplicationAdapter { logData.put("userId", userId); logData.put("oldConnId", connSessionId); logData.put("newConnId", sessionId); + logData.put("clientId", clientId); + logData.put("remoteAddress", remoteHost + ":" + remotePort); logData.put("event", "removing_defunct_connection"); logData.put("description", "Removing defunct connection BBB Video."); @@ -96,11 +101,17 @@ public class VideoApplication extends MultiThreadedApplicationAdapter { } } + String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); + int remotePort = Red5.getConnectionLocal().getRemotePort(); + String clientId = Red5.getConnectionLocal().getClient().getId(); + Map<String, Object> logData = new HashMap<String, Object>(); logData.put("meetingId", meetingId); logData.put("userId", userId); logData.put("connType", connType); logData.put("connId", sessionId); + logData.put("clientId", clientId); + logData.put("remoteAddress", remoteHost + ":" + remotePort); logData.put("event", "user_joining_bbb_video"); logData.put("description", "User joining BBB Video."); diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java index ee600aab123798fba46d0dfd44e3963eba47a1ec..d508fa1f8f88316f7d5977935295fffc5e1d1673 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java @@ -138,6 +138,9 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter { for (IConnection conn : conns) { String connUserId = (String) conn.getAttribute("INTERNAL_USER_ID"); String connSessionId = conn.getSessionId(); + String clientId = conn.getClient().getId(); + String remoteHost = connection.getRemoteAddress(); + int remotePort = connection.getRemotePort(); if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) { conn.removeAttribute("INTERNAL_USER_ID"); Map<String, Object> logData = new HashMap<String, Object>(); @@ -145,6 +148,8 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter { logData.put("userId", userId); logData.put("oldConnId", connSessionId); logData.put("newConnId", sessionId); + logData.put("clientId", clientId); + logData.put("remoteAddress", remoteHost + ":" + remotePort); logData.put("event", "removing_defunct_connection"); logData.put("description", "Removing defunct connection BBB Apps."); @@ -173,14 +178,15 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter { String connId = Red5.getConnectionLocal().getSessionId(); String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); - int remotePort = Red5.getConnectionLocal().getRemotePort(); - + int remotePort = Red5.getConnectionLocal().getRemotePort(); + String clientId = Red5.getConnectionLocal().getClient().getId(); Map<String, Object> logData = new HashMap<String, Object>(); logData.put("meetingId", meetingId); logData.put("connType", connType); logData.put("connId", connId); - logData.put("conn", remoteHost + ":" + remotePort); + logData.put("clientId", clientId); + logData.put("remoteAddress", remoteHost + ":" + remotePort); logData.put("userId", userId); logData.put("externalUserId", externalUserID); logData.put("sessionId", sessionId); @@ -222,14 +228,15 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter { String connType = getConnectionType(Red5.getConnectionLocal().getType()); String userFullname = bbbSession.getUsername(); String connId = Red5.getConnectionLocal().getSessionId(); - + String clientId = Red5.getConnectionLocal().getClient().getId(); String sessionId = CONN + userId; Map<String, Object> logData = new HashMap<String, Object>(); logData.put("meetingId", meetingId); logData.put("connType", connType); logData.put("connId", connId); - logData.put("conn", remoteHost + ":" + remotePort); + logData.put("clientId", clientId); + logData.put("remoteAddress", remoteHost + ":" + remotePort); logData.put("sessionId", sessionId); logData.put("userId", userId); logData.put("username", userFullname); diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as index 1c4f27e3a64fd24ad8cc41d782fa9c997af2453d..0ab10e7dd69c7bb9a315d0c64506df1de94039fd 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as @@ -144,7 +144,7 @@ package org.bigbluebutton.main.model try { var logData:Object = UsersUtil.initLogData(); logData.connection = this.baseURI; - logData.tags = ["connection"]; + logData.tags = ["initialization", "port-test", "connection"]; logData.message = "Port testing connection."; LOGGER.info(JSON.stringify(logData)); @@ -168,7 +168,7 @@ package org.bigbluebutton.main.model public function connectionTimeout (e:TimerEvent) : void { var logData:Object = UsersUtil.initLogData(); logData.connection = this.baseURI; - logData.tags = ["connection"]; + logData.tags = ["initialization", "port-test", "connection"]; logData.message = "Port testing connection timedout."; LOGGER.info(JSON.stringify(logData)); @@ -200,7 +200,7 @@ package org.bigbluebutton.main.model private function closeConnectionTimerHandler (e:TimerEvent) : void { var logData:Object = UsersUtil.initLogData(); logData.connection = this.baseURI; - logData.tags = ["connection"]; + logData.tags = ["initialization", "port-test", "connection"]; logData.message = "Closing port testing connection."; LOGGER.info(JSON.stringify(logData)); @@ -222,7 +222,7 @@ package org.bigbluebutton.main.model var logData:Object = UsersUtil.initLogData(); logData.connection = this.baseURI; - logData.tags = ["connection"]; + logData.tags = ["initialization", "port-test", "connection"]; if ( statusCode == "NetConnection.Connect.Success" ) { diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as index a5cac6a9fd97a0b856f979517fbf51c55f2f45c7..ce92a8f875ecc6cbc3694b8dc4088c27cf00356c 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/EnterApiService.as @@ -70,15 +70,18 @@ package org.bigbluebutton.main.model.modules var dispatcher:Dispatcher = new Dispatcher(); dispatcher.dispatchEvent(new MeetingNotFoundEvent(result.response.logoutURL)); } else if (returncode == 'SUCCESS') { - logData.tags = ["initialization"]; - logData.message = "Enter API call succeeded."; - LOGGER.info(JSON.stringify(logData)); + var response:Object = new Object(); response.username = result.response.fullname; response.userId = result.response.internalUserID; response.meetingName = result.response.confname; response.meetingId = result.response.meetingID; + + logData.response = response; + logData.tags = ["initialization"]; + logData.message = "Enter API call succeeded."; + LOGGER.info(JSON.stringify(logData)); if (_resultListener != null) _resultListener(true, response); } 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 7b5cad45d88fa94b13458a3bf211cfa1104c1c06..35356beada6d35a34519df52d06e0702e15b564e 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as @@ -26,7 +26,7 @@ package org.bigbluebutton.main.model.users import flash.events.TimerEvent; import flash.net.NetConnection; import flash.net.Responder; - import flash.utils.Timer; + import flash.utils.Timer; import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.getClassLogger; import org.bigbluebutton.core.BBB; @@ -40,358 +40,396 @@ package org.bigbluebutton.main.model.users import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent; import org.bigbluebutton.main.model.users.events.UsersConnectionEvent; - public class NetConnectionDelegate - { - private static const LOGGER:ILogger = getClassLogger(NetConnectionDelegate); - - private var _netConnection:NetConnection; - private var connectionId:Number; - private var connected:Boolean = false; - - private var _userid:Number = -1; - private var _role:String = "unknown"; - - private var logoutOnUserCommand:Boolean = false; - private var dispatcher:Dispatcher; - private var _messageListeners:Array = new Array(); - - private var authenticated: Boolean = false; - private var reconnecting:Boolean = false; - private var numNetworkChangeCount:int = 0; - - private var _validateTokenTimer:Timer = null; - - public function NetConnectionDelegate():void { - dispatcher = new Dispatcher(); - } - - public function get connection():NetConnection { - return _netConnection; - } + public class NetConnectionDelegate { + private static const LOGGER:ILogger = getClassLogger(NetConnectionDelegate); + + private var _netConnection:NetConnection; + private var connectionId:Number; + private var connected:Boolean = false; + private var _userid:Number = -1; + private var _role:String = "unknown"; + private var logoutOnUserCommand:Boolean = false; + private var dispatcher:Dispatcher; + private var _messageListeners:Array = new Array(); + private var authenticated: Boolean = false; + private var reconnecting:Boolean = false; - public function addMessageListener(listener:IMessageListener):void { - _messageListeners.push(listener); - } + private var maxConnectAttempt:int = 2; + private var connectAttemptCount:int = 0; + private var connectAttemptTimeout:Number = 5000; + private var connectionTimer:Timer; + + private var numNetworkChangeCount:int = 0; + private var _validateTokenTimer:Timer = null; + + private var bbbAppsUrl: String = null; - public function removeMessageListener(listener:IMessageListener):void { - for (var ob:int=0; ob<_messageListeners.length; ob++) { - if (_messageListeners[ob] == listener) { - _messageListeners.splice (ob,1); - break; + public function NetConnectionDelegate():void { + dispatcher = new Dispatcher(); } - } - } + - private function notifyListeners(messageName:String, message:Object):void { - if (messageName != null && messageName != "") { - for (var notify:String in _messageListeners) { - _messageListeners[notify].onMessage(messageName, message); - } - } else { - LOGGER.debug("Message name is undefined"); - } - } + public function get connection():NetConnection { + return _netConnection; + } + + public function addMessageListener(listener:IMessageListener):void { + _messageListeners.push(listener); + } + + public function removeMessageListener(listener:IMessageListener):void { + for (var ob:int=0; ob<_messageListeners.length; ob++) { + if (_messageListeners[ob] == listener) { + _messageListeners.splice (ob,1); + break; + } + } + } + + private function notifyListeners(messageName:String, message:Object):void { + if (messageName != null && messageName != "") { + for (var notify:String in _messageListeners) { + _messageListeners[notify].onMessage(messageName, message); + } + } else { + LOGGER.debug("Message name is undefined"); + } + } + + public function onMessageFromServer(messageName:String, msg:Object):void { + if (!authenticated && (messageName == "validateAuthTokenReply")) { + handleValidateAuthTokenReply(msg) + } else if (messageName == "validateAuthTokenTimedOut") { + handleValidateAuthTokenTimedOut(msg) + } else if (authenticated) { + notifyListeners(messageName, msg); + } else { + LOGGER.debug("Ignoring message=[{0}] as our token hasn't been validated yet.", [messageName]); + } + } + + private function validataTokenTimerHandler(event:TimerEvent):void { + var logData:Object = UsersUtil.initLogData(); + logData.tags = ["apps"]; + logData.key = "validate_token_request_timedout"; + logData.message = "No response for validate token request."; + LOGGER.info(JSON.stringify(logData)); + } + + private function validateToken():void { + var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams(); + + var message:Object = new Object(); + message["userId"] = confParams.internalUserID; + message["authToken"] = confParams.authToken; + + _validateTokenTimer = new Timer(7000, 1); + _validateTokenTimer.addEventListener(TimerEvent.TIMER, validataTokenTimerHandler); + _validateTokenTimer.start(); + + sendMessage( + "validateToken",// Remote function name + // result - On successful result + function(result:Object):void { + + }, + // status - On error occurred + function(status:Object):void { + LOGGER.error("Error occurred:"); + for (var x:Object in status) { + LOGGER.error(x + " : " + status[x]); + } + }, + message + ); //_netConnection.call + } - public function onMessageFromServer(messageName:String, msg:Object):void { - if (!authenticated && (messageName == "validateAuthTokenReply")) { - handleValidateAuthTokenReply(msg) - } else if (messageName == "validateAuthTokenTimedOut") { - handleValidateAuthTokenTimedOut(msg) - } else if (authenticated) { - notifyListeners(messageName, msg); - } else { - LOGGER.debug("Ignoring message=[{0}] as our token hasn't been validated yet.", [messageName]); - } - } - - private function validataTokenTimerHandler(event:TimerEvent):void { - var logData:Object = UsersUtil.initLogData(); - logData.tags = ["apps"]; - logData.message = "No response for validate token request."; - LOGGER.info(JSON.stringify(logData)); - } - - private function validateToken():void { - var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams(); - - var message:Object = new Object(); - message["userId"] = confParams.internalUserID; - message["authToken"] = confParams.authToken; + private function stopValidateTokenTimer():void { + if (_validateTokenTimer != null && _validateTokenTimer.running) { + _validateTokenTimer.stop(); + _validateTokenTimer = null; + } + } + + private function handleValidateAuthTokenTimedOut(msg: Object):void { + stopValidateTokenTimer(); - _validateTokenTimer = new Timer(7000, 1); - _validateTokenTimer.addEventListener(TimerEvent.TIMER, validataTokenTimerHandler); - _validateTokenTimer.start(); - - sendMessage( - "validateToken",// Remote function name - // result - On successful result - function(result:Object):void { - - }, - // status - On error occurred - function(status:Object):void { - LOGGER.error("Error occurred:"); - for (var x:Object in status) { - LOGGER.error(x + " : " + status[x]); - } - }, - 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; - - var logData:Object = UsersUtil.initLogData(); - logData.tags = ["apps"]; - logData.message = "Validate auth token timed out."; - LOGGER.info(JSON.stringify(logData)); - - if (tokenValid) { - authenticated = true; - } else { - dispatcher.dispatchEvent(new InvalidAuthTokenEvent()); - } - if (reconnecting) { - onReconnect(); - reconnecting = false; - } - } - - 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; + var map:Object = JSON.parse(msg.msg); + var tokenValid: Boolean = map.valid as Boolean; + var userId: String = map.userId as String; + + var logData:Object = UsersUtil.initLogData(); + logData.tags = ["apps", "connected"]; + logData.tokenValid = tokenValid; + logData.key = "validate_token_response_received"; + logData.message = "Validate auth token timed out."; + LOGGER.info(JSON.stringify(logData)); - if (tokenValid) { - authenticated = true; - } else { - dispatcher.dispatchEvent(new InvalidAuthTokenEvent()); - } - if (reconnecting) { - onReconnect(); - reconnecting = false; - } - } + if (tokenValid) { + authenticated = true; + } else { + dispatcher.dispatchEvent(new InvalidAuthTokenEvent()); + } - private function onReconnect():void { - if (authenticated) { - onReconnectSuccess(); - } else { - onReconnectFailed(); - } - } - - private function onReconnectSuccess():void { - var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT); - attemptSucceeded.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; - dispatcher.dispatchEvent(attemptSucceeded); - } + if (reconnecting) { + onReconnect(); + reconnecting = false; + } + } + + private function handleValidateAuthTokenReply(msg: Object):void { + stopValidateTokenTimer(); - private function onReconnectFailed():void { - sendUserLoggedOutEvent(); - } - - private function sendConnectionSuccessEvent(userid:String):void{ - var e:UsersConnectionEvent = new UsersConnectionEvent(UsersConnectionEvent.CONNECTION_SUCCESS); - e.userid = userid; - dispatcher.dispatchEvent(e); + var map:Object = JSON.parse(msg.msg); + var tokenValid: Boolean = map.valid as Boolean; + var userId: String = map.userId as String; + + var logData:Object = UsersUtil.initLogData(); + logData.tags = ["apps", "connected"]; + logData.tokenValid = tokenValid; + logData.key = "validate_token_response_received"; + logData.message = "Received validate token response from server."; + LOGGER.info(JSON.stringify(logData)); + + if (tokenValid) { + authenticated = true; + } else { + dispatcher.dispatchEvent(new InvalidAuthTokenEvent()); + } - } - - public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object=null):void { - var responder:Responder = new Responder( - function(result:Object):void { // On successful result - onSuccess("Successfully sent [" + service + "]."); - }, - function(status:Object):void { // status - On error occurred - var errorReason:String = "Failed to send [" + service + "]:\n"; - for (var x:Object in status) { - errorReason += "\t" + x + " : " + status[x]; - } - } - ); - - if (message == null) { - _netConnection.call(service, responder); - } else { - _netConnection.call(service, responder, message); - } - } - - /** - * Connect to the server. - * uri: The uri to the conference application. - * username: Fullname of the participant. - * role: MODERATOR/VIEWER - * conference: The conference room - * mode: LIVE/PLAYBACK - Live:when used to collaborate, Playback:when being used to playback a recorded conference. - * room: Need the room number when playing back a recorded conference. When LIVE, the room is taken from the URI. - */ - public function connect():void { - var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams(); - - _netConnection = new NetConnection(); - _netConnection.proxyType = "best"; - _netConnection.client = this; - _netConnection.addEventListener( NetStatusEvent.NET_STATUS, netStatus ); - _netConnection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, netASyncError ); - _netConnection.addEventListener( SecurityErrorEvent.SECURITY_ERROR, netSecurityError ); - _netConnection.addEventListener( IOErrorEvent.IO_ERROR, netIOError ); + if (reconnecting) { + onReconnect(); + reconnecting = false; + } + } + + private function onReconnect():void { + if (authenticated) { + onReconnectSuccess(); + } else { + onReconnectFailed(); + } + } + + private function onReconnectSuccess():void { + var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT); + attemptSucceeded.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; + dispatcher.dispatchEvent(attemptSucceeded); + } + + private function onReconnectFailed():void { + sendUserLoggedOutEvent(); + } + + private function sendConnectionSuccessEvent(userid:String):void{ + var e:UsersConnectionEvent = new UsersConnectionEvent(UsersConnectionEvent.CONNECTION_SUCCESS); + e.userid = userid; + dispatcher.dispatchEvent(e); + } + + public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object=null):void { + var responder:Responder = new Responder( + function(result:Object):void { // On successful result + onSuccess("Successfully sent [" + service + "]."); + }, + function(status:Object):void { // status - On error occurred + var errorReason:String = "Failed to send [" + service + "]:\n"; + for (var x:Object in status) { + errorReason += "\t" + x + " : " + status[x]; + } + } + ); + + if (message == null) { + _netConnection.call(service, responder); + } else { + _netConnection.call(service, responder, message); + } + } + + public function connect():void { + var confParams:ConferenceParameters = BBB.initUserConfigManager().getConfParams(); + + _netConnection = new NetConnection(); + _netConnection.proxyType = "best"; + _netConnection.client = this; + _netConnection.addEventListener( NetStatusEvent.NET_STATUS, netStatus ); + _netConnection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, netASyncError ); + _netConnection.addEventListener( SecurityErrorEvent.SECURITY_ERROR, netSecurityError ); + _netConnection.addEventListener( IOErrorEvent.IO_ERROR, netIOError ); + + try { + var appURL:String = BBB.getConfigManager().config.application.uri; + var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/; + var result:Array = pattern.exec(appURL); + + var protocol:String = "rtmp"; + var uri:String = appURL + "/" + confParams.room; + + if (BBB.initConnectionManager().isTunnelling) { + bbbAppsUrl = "rtmpt://" + result.server + "/" + result.app + "/" + confParams.room; + } else { + bbbAppsUrl = "rtmp://" + result.server + ":1935/" + result.app + "/" + confParams.room; + } + + var logData:Object = UsersUtil.initLogData(); + logData.connection = bbbAppsUrl; + logData.tags = ["apps", "connection"]; + logData.message = "Connecting to bbb-apps."; + LOGGER.info(JSON.stringify(logData)); - try { - var appURL:String = BBB.getConfigManager().config.application.uri; - var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/; - var result:Array = pattern.exec(appURL); + connectAttemptCount++; + + connectionTimer = new Timer(connectAttemptTimeout, 1); + connectionTimer.addEventListener(TimerEvent.TIMER, connectionTimeout); + connectionTimer.start(); + + _netConnection.connect(uri, confParams.username, confParams.role, + confParams.room, confParams.voicebridge, + confParams.record, confParams.externUserID, + confParams.internalUserID, confParams.muteOnStart, confParams.lockSettings); + + } catch(e:ArgumentError) { + // Invalid parameters. + switch (e.errorID) { + case 2004 : + LOGGER.debug("Error! Invalid server location: {0}", [uri]); + break; + default : + LOGGER.debug("UNKNOWN Error! Invalid server location: {0}", [uri]); + break; + } + } + } + + public function connectionTimeout (e:TimerEvent) : void { + var logData:Object = UsersUtil.initLogData(); + logData.connection = bbbAppsUrl; + logData.tags = ["apps", "connection"]; + logData.connectAttemptCount = connectAttemptCount; + logData.message = "Connecting attempt to bbb-apps timedout. Retrying."; + LOGGER.info(JSON.stringify(logData)); + + if (connectAttemptCount <= maxConnectAttempt) { + connect(); + } else { + sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_ATTEMPT_TIMEDOUT); + } + + } + + + public function disconnect(logoutOnUserCommand:Boolean):void { + this.logoutOnUserCommand = logoutOnUserCommand; + _netConnection.close(); + } - var protocol:String = "rtmp"; - var uri:String = appURL + "/" + confParams.room; + public function forceClose():void { + _netConnection.close(); + } - if (BBB.initConnectionManager().isTunnelling) { - uri = "rtmpt://" + result.server + "/" + result.app + "/" + confParams.room; - } else { - uri = "rtmp://" + result.server + ":1935/" + result.app + "/" + confParams.room; + protected function netStatus(event:NetStatusEvent):void { + handleResult( event ); } - - - LOGGER.debug("BBB Apps URI=" + uri); - - _netConnection.connect(uri, confParams.username, confParams.role, - confParams.room, confParams.voicebridge, - confParams.record, confParams.externUserID, - confParams.internalUserID, confParams.muteOnStart, confParams.lockSettings); - - } catch(e:ArgumentError) { - // Invalid parameters. - switch (e.errorID) { - case 2004 : - LOGGER.debug("Error! Invalid server location: {0}", [uri]); - break; - default : - LOGGER.debug("UNKNOWN Error! Invalid server location: {0}", [uri]); - break; - } - } - } - - public function disconnect(logoutOnUserCommand:Boolean):void { - this.logoutOnUserCommand = logoutOnUserCommand; - _netConnection.close(); - } - - - public function forceClose():void { - _netConnection.close(); - } - - protected function netStatus(event:NetStatusEvent):void { - handleResult( event ); - } - - public function handleResult(event:Object):void { - var info : Object = event.info; - var statusCode : String = info.code; + + public function handleResult(event:Object):void { + var info : Object = event.info; + var statusCode : String = info.code; + + //Stop timeout timer when connected/rejected + if (connectionTimer != null && connectionTimer.running) { + connectionTimer.stop(); + connectionTimer = null; + } + var logData:Object = UsersUtil.initLogData(); - logData.tags = ["apps"]; - - switch (statusCode) { - case "NetConnection.Connect.Success": - numNetworkChangeCount = 0; - logData.message = "Successfully connected to BBB App."; + logData.tags = ["apps", "connection"]; + + switch (statusCode) { + case "NetConnection.Connect.Success": + numNetworkChangeCount = 0; + logData.message = "Successfully connected to bbb-apps."; LOGGER.info(JSON.stringify(logData)); validateToken(); - break; - - case "NetConnection.Connect.Failed": - logData.message = "Connection to bbb-apps failed, even when tunneling."; + break; + + case "NetConnection.Connect.Failed": + logData.message = "Connection to bbb-apps failed."; + LOGGER.info(JSON.stringify(logData)); + sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_FAILED); + break; + + case "NetConnection.Connect.Closed": + logData.message = "NetConnection.Connect.Closed on bbb-apps"; LOGGER.info(JSON.stringify(logData)); - sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_FAILED); - break; - - case "NetConnection.Connect.Closed": - logData.message = "NetConnection.Connect.Closed on bbb-apps"; - LOGGER.info(JSON.stringify(logData)); - sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_CLOSED); - break; - - case "NetConnection.Connect.InvalidApp": + sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_CLOSED); + break; + + case "NetConnection.Connect.InvalidApp": logData.message = "bbb-app not found."; LOGGER.info(JSON.stringify(logData)); - sendConnectionFailedEvent(ConnectionFailedEvent.INVALID_APP); - break; - - case "NetConnection.Connect.AppShutDown": + sendConnectionFailedEvent(ConnectionFailedEvent.INVALID_APP); + break; + + case "NetConnection.Connect.AppShutDown": LOGGER.debug(":viewers application has been shutdown"); - sendConnectionFailedEvent(ConnectionFailedEvent.APP_SHUTDOWN); - break; - - case "NetConnection.Connect.Rejected": - var appURL:String = BBB.getConfigManager().config.application.uri - LOGGER.debug(":Connection to the server rejected. Uri: {0}. Check if the red5 specified in the uri exists and is running", [appURL]); - sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_REJECTED); - break; - - case "NetConnection.Connect.NetworkChange": - numNetworkChangeCount++; - if (numNetworkChangeCount % 20 == 0) { - logData.message = "Detected network change on bbb-apps"; - logData.numNetworkChangeCount = numNetworkChangeCount; - LOGGER.info(JSON.stringify(logData)); - } - break; - - default : - LOGGER.debug(":Default status to the viewers application" ); - sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); - break; - } - } - - protected function netSecurityError(event: SecurityErrorEvent):void { + sendConnectionFailedEvent(ConnectionFailedEvent.APP_SHUTDOWN); + break; + + case "NetConnection.Connect.Rejected": + var appURL:String = BBB.getConfigManager().config.application.uri + LOGGER.debug(":Connection to the server rejected. Uri: {0}. Check if the red5 specified in the uri exists and is running", [appURL]); + sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_REJECTED); + break; + + case "NetConnection.Connect.NetworkChange": + numNetworkChangeCount++; + if (numNetworkChangeCount % 20 == 0) { + logData.message = "Detected network change on bbb-apps"; + logData.numNetworkChangeCount = numNetworkChangeCount; + LOGGER.info(JSON.stringify(logData)); + } + break; + + default : + LOGGER.debug(":Default status to the viewers application" ); + sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); + break; + } + } + + protected function netSecurityError(event: SecurityErrorEvent):void { var logData:Object = UsersUtil.initLogData(); - logData.tags = ["apps"]; + logData.tags = ["apps", "connection"]; logData.message = "Security error - " + event.text; LOGGER.info(JSON.stringify(logData)); - sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); - } - - protected function netIOError(event: IOErrorEvent):void { + sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); + } + + protected function netIOError(event: IOErrorEvent):void { var logData:Object = UsersUtil.initLogData(); - logData.tags = ["apps"]; + logData.tags = ["apps", "connection"]; logData.message = "Input/output error - " + event.text; LOGGER.info(JSON.stringify(logData)); - sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); - } - - protected function netASyncError(event: AsyncErrorEvent):void { - LOGGER.debug("Asynchronous code error - {0}", [event.toString()]); - sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); - } - + sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); + } + + protected function netASyncError(event: AsyncErrorEvent):void { + LOGGER.debug("Asynchronous code error - {0}", [event.toString()]); + sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); + } + private function sendConnectionFailedEvent(reason:String):void{ var logData:Object = UsersUtil.initLogData(); - logData.tags = ["apps"]; + logData.tags = ["apps", "connection"]; if (this.logoutOnUserCommand) { logData.reason = "User requested."; logData.message = "User logged out from BBB App."; LOGGER.info(JSON.stringify(logData)); - + sendUserLoggedOutEvent(); } else if (reason == ConnectionFailedEvent.CONNECTION_CLOSED && !UsersUtil.isUserEjected()) { // do not try to reconnect if the connection failed is different than CONNECTION_CLOSED @@ -400,20 +438,19 @@ package org.bigbluebutton.main.model.users LOGGER.info(JSON.stringify(logData)); if (reconnecting) { - var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT); - attemptFailedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; - dispatcher.dispatchEvent(attemptFailedEvent); + var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT); + attemptFailedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; + dispatcher.dispatchEvent(attemptFailedEvent); } else { - reconnecting = true; - authenticated = false; - - var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT); - disconnectedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; - disconnectedEvent.payload.callback = connect; - disconnectedEvent.payload.callbackParameters = new Array(); - dispatcher.dispatchEvent(disconnectedEvent); - } + reconnecting = true; + authenticated = false; + var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT); + disconnectedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; + disconnectedEvent.payload.callback = connect; + disconnectedEvent.payload.callbackParameters = new Array(); + dispatcher.dispatchEvent(disconnectedEvent); + } } else { if (UsersUtil.isUserEjected()) { logData.message = "User has been ejected from meeting."; @@ -428,22 +465,22 @@ package org.bigbluebutton.main.model.users } } - - private function sendUserLoggedOutEvent():void{ - var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT); - dispatcher.dispatchEvent(e); - } - - public function onBWCheck(... rest):Number { - return 0; - } - - public function onBWDone(... rest):void { - var p_bw:Number; - if (rest.length > 0) p_bw = rest[0]; - // your application should do something here - // when the bandwidth check is complete - LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]); - } - } + + private function sendUserLoggedOutEvent():void{ + var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT); + dispatcher.dispatchEvent(e); + } + + public function onBWCheck(... rest):Number { + return 0; + } + + public function onBWDone(... rest):void { + var p_bw:Number; + if (rest.length > 0) p_bw = rest[0]; + // your application should do something here + // when the bandwidth check is complete + LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]); + } + } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as index 6ceb8b8efd29258a32fa63ddcc7f523a8df3af4e..f6b8530e5a99d5138daeff5fc225127aadf836be 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as +++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/events/ConnectionFailedEvent.as @@ -18,23 +18,22 @@ */ package org.bigbluebutton.main.model.users.events { - import flash.events.Event; + import flash.events.Event; - public class ConnectionFailedEvent extends Event - { - public static const UNKNOWN_REASON:String = "unknownReason"; - public static const CONNECTION_FAILED:String = "connectionFailed"; - public static const CONNECTION_CLOSED:String = "connectionClosed"; - public static const INVALID_APP:String = "invalidApp"; - public static const APP_SHUTDOWN:String = "appShutdown"; - public static const CONNECTION_REJECTED:String = "connectionRejected"; - public static const ASYNC_ERROR:String = "asyncError"; - public static const USER_LOGGED_OUT:String = "userHasLoggedOut"; - public static const USER_EJECTED_FROM_MEETING:String = "userHasBeenEjectFromMeeting"; - - public function ConnectionFailedEvent(type:String) - { - super(type, true, false); - } - } + public class ConnectionFailedEvent extends Event { + public static const UNKNOWN_REASON:String = "unknownReason"; + public static const CONNECTION_FAILED:String = "connectionFailed"; + public static const CONNECTION_CLOSED:String = "connectionClosed"; + public static const CONNECTION_ATTEMPT_TIMEDOUT:String = "connectionAttemptTimedout"; + public static const INVALID_APP:String = "invalidApp"; + public static const APP_SHUTDOWN:String = "appShutdown"; + public static const CONNECTION_REJECTED:String = "connectionRejected"; + public static const ASYNC_ERROR:String = "asyncError"; + public static const USER_LOGGED_OUT:String = "userHasLoggedOut"; + public static const USER_EJECTED_FROM_MEETING:String = "userHasBeenEjectFromMeeting"; + + public function ConnectionFailedEvent(type:String) { + super(type, true, false); + } + } } \ No newline at end of file diff --git a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy index cb9a9ffbfb21087aa9285e888ad4fcad7c672d51..01e641cd98585163e011b320640b1f20eb256f61 100755 --- a/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy +++ b/bigbluebutton-web/grails-app/controllers/org/bigbluebutton/web/controllers/ApiController.groovy @@ -18,6 +18,8 @@ */ package org.bigbluebutton.web.controllers +import com.google.gson.Gson + import javax.servlet.ServletRequest; import java.net.URI; @@ -1455,7 +1457,7 @@ class ApiController { reject = true } else { sessionToken = StringUtils.strip(params.sessionToken) - log.info("SessionToken = " + sessionToken) + log.info("Getting ConfigXml for SessionToken = " + sessionToken) if (!session[sessionToken]) { reject = true } else { @@ -1478,6 +1480,20 @@ class ApiController { } } } else { + Map<String, Object> logData = new HashMap<String, Object>(); + logData.put("meetingId", us.meetingID); + logData.put("externalMeetingId", us.externMeetingID); + logData.put("name", us.fullname); + logData.put("userId", us.internalUserId); + logData.put("sessionToken", sessionToken); + logData.put("message", "handle_configxml_api"); + logData.put("description", "Handling ConfigXml API."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + + log.info(logStr); + response.addHeader("Cache-Control", "no-cache") render text: us.configXML, contentType: 'text/xml' } @@ -1544,7 +1560,20 @@ class ApiController { // how many times a user reconnects or refresh the browser. String newInternalUserID = us.internalUserId + "_" + us.incrementConnectionNum() - log.info("Found conference for " + us.fullname) + Map<String, Object> logData = new HashMap<String, Object>(); + logData.put("meetingId", us.meetingID); + logData.put("externalMeetingId", us.externMeetingID); + logData.put("name", us.fullname); + logData.put("userId", newInternalUserID); + logData.put("sessionToken", sessionToken); + logData.put("message", "handle_enter_api"); + logData.put("description", "Handling ENTER API."); + + Gson gson = new Gson(); + String logStr = gson.toJson(logData); + + log.info(logStr); + response.addHeader("Cache-Control", "no-cache") withFormat { json {