Merge remote-tracking branch 'upstream/master' into breakout-rooms-html5

* upstream/master: (22 commits)
  - create only one netConnection to bbb-apps. Not re-create one when reconnecting.
  - log client out when user is ejected from meeting.
  - reset connectAttemptTimeout as we don't want to fail connection on reconnects.
  - fix rtmpt
  - add more logging to track issues
  Update Gemfile.lock for 1.1-dev
  - log locale version
  - remove user join log
  improve logs for webrtc events
  - improve client side logging.
  add EN string to ClientStatusEvent
  Updated restart of libreoffice for systemd
  - add log to indicate successful connection to bbb-apss
  bbb-web: Escaped strings used in freemarker template for thumbnails
  record-and-playback: Removed preview extension (thumbnails) from recordings when only has default presentation
  Fix import in stunturn reply handler
  Fix handleStunTurnReply function name
  Clean up before PR
  Rever wrong changes on chat handler parameters
  Revert wrong changes on chat handler name
  ...
This commit is contained in:
Gabriel Carvalho de Campes 2016-11-14 10:00:42 -02:00
commit 3f53620416
63 changed files with 1650 additions and 1060 deletions

View File

@ -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.");

View File

@ -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);

View File

@ -145,8 +145,8 @@ public class ConnectionInvokerService {
private void handlDisconnectClientMessage(DisconnectClientMessage msg) {
IScope meetingScope = getScope(msg.getMeetingId());
if (meetingScope != null) {
String sessionId = CONN + msg.getUserId();
IConnection conn = getConnection(meetingScope, sessionId);
String userId = msg.getUserId();
IConnection conn = getConnection(meetingScope, userId);
if (conn != null) {
if (conn.isConnected()) {
log.info("Disconnecting user=[{}] from meeting=[{}]", msg.getUserId(), msg.getMeetingId());

View File

@ -25,7 +25,8 @@ package org.bigbluebutton.core
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.core.vo.CameraSettingsVO;
import org.bigbluebutton.main.model.users.BBBUser;
import org.bigbluebutton.util.SessionTokenUtil;
public class UsersUtil
{
@ -194,7 +195,7 @@ package org.bigbluebutton.core
return null;
}
public static function getUserData():Object {
private static function getUserData():Object {
var userData:Object = new Object();
userData.meetingId = getInternalMeetingID();
userData.externalMeetingId = getExternalMeetingID();
@ -215,5 +216,20 @@ package org.bigbluebutton.core
return false;
}
public static function initLogData():Object {
var logData:Object = new Object();
if (getInternalMeetingID() != null) {
logData.user = UsersUtil.getUserData();
}
logData.sessionToken = getUserSession();
return logData;
}
public static function getUserSession():String {
var sessionUtil:SessionTokenUtil = new SessionTokenUtil()
return sessionUtil.getSessionToken();
}
}
}

View File

@ -85,12 +85,9 @@ package org.bigbluebutton.core.managers
public function onDisconnected(type:String, callback:Function, parameters:Array):void {
if (!_canceled) {
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.user.connection = type;
JSLog.warn("Connection disconnected", logData);
logData.tags = ["connection"];
logData.message = "Connection disconnected";
LOGGER.info(JSON.stringify(logData));
@ -110,14 +107,9 @@ package org.bigbluebutton.core.managers
}
public function onConnectionAttemptFailed(type:String):void {
LOGGER.warn("onConnectionAttemptFailed, type={0}", [type]);
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
logData.user.connection = type;
JSLog.warn("Reconnect attempt on connection failed.", logData);
var logData:Object = UsersUtil.initLogData();
logData.user.connection = type;
logData.tags = ["connection"];
logData.message = "Reconnect attempt on connection failed.";
LOGGER.info(JSON.stringify(logData));
@ -150,18 +142,13 @@ package org.bigbluebutton.core.managers
}
public function onConnectionAttemptSucceeded(type:String):void {
LOGGER.debug("onConnectionAttemptSucceeded, type={0}", [type]);
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.user.connection = type;
JSLog.warn("Reconnect succeeded.", logData);
logData.tags = ["connection"];
logData.message = "Reconnect succeeded.";
LOGGER.info(JSON.stringify(logData));
dispatchReconnectionSucceededEvent(type);
delete _connections[type];
if (type == BIGBLUEBUTTON_CONNECTION) {
reconnect();
@ -173,7 +160,7 @@ package org.bigbluebutton.core.managers
_dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT,
ResourceUtil.getInstance().getString('bbb.connection.reestablished'),
msg));
msg, 'bbb.connection.reestablished'));
_reconnectTimeout.reset();
removePopUp();

View File

@ -19,10 +19,10 @@
package org.bigbluebutton.core.model
{
import flash.utils.Dictionary;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.util.i18n.ResourceUtil;
public class VideoProfile
{
@ -89,8 +89,11 @@ package org.bigbluebutton.core.model
_h264Profile = vxml.h264Profile.toString();
}
LOGGER.debug("This is a new video profile");
LOGGER.debug(this.toString());
var logData:Object = UsersUtil.initLogData();
logData.videoProfile = this.toString();
logData.tags = ["video"];
logData.message = "Loaded new video profile.";
LOGGER.info(JSON.stringify(logData));
}
public function toString():String {

View File

@ -29,12 +29,14 @@ package org.bigbluebutton.main.events
public var title:String;
public var message:String;
public function ClientStatusEvent(type:String, title:String, message:String)
public var logCode:String;
public function ClientStatusEvent(type:String, title:String, message:String, logCode:String)
{
super(type);
this.title = title;
this.message = message;
this.logCode = logCode;
}
}
}
}

View File

@ -1,3 +1,265 @@
/** * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ * * Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). * * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free Software * Foundation; either version 3.0 of the License, or (at your option) any later * version. * * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. * */ package org.bigbluebutton.main.model { import flash.events.NetStatusEvent; import flash.events.TimerEvent; import flash.net.NetConnection; import flash.net.ObjectEncoding; import flash.utils.Timer; import flash.utils.Dictionary; import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.getClassLogger; [Bindable] /** * Test RTMP port. * * @author Thijs Triemstra ( info@collab.nl ) */ public class PortTest { private static const LOGGER:ILogger = getClassLogger(PortTest); /** * Connect using rtmp or rtmpt. */ private var tunnel: Boolean; /** * RTMP hostname. */ private var hostname : String; /** * RTMP port. */ public var port : String; /** * RTMP port. */ public var portName : String = "Default"; /** * RTMP application. */ private var application : String; /** * Base RTMP URI. */ private var baseURI : String; /** * RTMP connection. */ public var nc : NetConnection; /** * Connection status. */ public var status : String; private var _connectionListener:Function; /** * Timer to control timeout of connection test */ private var testTimeout:Number = 0; /** * Timer to control timeout of connection test */ private var connectionTimer:Timer; private var closeConnectionTimer:Timer; /** * Set default encoding to AMF0 so FMS also understands. */ NetConnection.defaultObjectEncoding = ObjectEncoding.AMF0; /** * Create new port test and connect to the RTMP server. * * @param protocol * @param hostname * @param port * @param application * @testTimeout timeout of test in milliseconds */ public function PortTest( tunnel : Boolean, hostname : String = "", port : String = "", application : String = "", testTimeout : Number = 10000) { this.tunnel = tunnel; this.hostname = hostname; this.application = application; this.testTimeout = testTimeout; if ( port.length > 0 ) { this.portName = port; this.port = ":" + port; } else { this.port = port; } // Construct URI. if (tunnel) { this.baseURI = "rtmpt://" + this.hostname + "/" + this.application; } else { this.baseURI = "rtmp://" + this.hostname + this.port + "/" + this.application; } } /** * Start connection. */ public function connect():void { nc = new NetConnection(); nc.client = this;
nc.proxyType = "best";
nc.addEventListener( NetStatusEvent.NET_STATUS, netStatus ); // connect to server try { LOGGER.debug("Testing connection to " + this.baseURI); connectionTimer = new Timer(testTimeout, 1); connectionTimer.addEventListener(TimerEvent.TIMER, connectionTimeout); connectionTimer.start(); var curTime:Number = new Date().getTime(); // Create connection with the server. nc.connect( this.baseURI, "portTestMeetingId-" + curTime, "portTestDummyUserId-" + curTime); status = "Connecting..."; } catch( e : ArgumentError ) { // Invalid parameters. status = "ERROR: " + e.message; } } /** * Method called when connection timed out */ public function connectionTimeout (e:TimerEvent) : void { LOGGER.debug("Timedout trying to connect to " + this.baseURI); status = "FAILED"; _connectionListener(status, tunnel, hostname, port, application); closeConnection(); } /** * Close connection. */ private function close():void { LOGGER.debug("Closing port test connection."); var dc:Dictionary = new Dictionary(true); nc.client = dc; // Remove listener. nc.removeEventListener( NetStatusEvent.NET_STATUS, netStatus ); // Close the NetConnection. nc.close(); } private function closeConnection():void { closeConnectionTimer = new Timer(100, 1); closeConnectionTimer.addEventListener(TimerEvent.TIMER, closeConnectionTimerHandler); closeConnectionTimer.start(); } private function closeConnectionTimerHandler (e:TimerEvent) : void { LOGGER.debug("Closing connection to " + this.baseURI); close(); } /** * Catch NetStatusEvents. * * @param event */ protected function netStatus(event : NetStatusEvent):void { //Stop timeout timer when connected/rejected connectionTimer.stop(); var info : Object = event.info; var statusCode : String = info.code; if ( statusCode == "NetConnection.Connect.Success" ) { status = "SUCCESS"; LOGGER.debug("Successfully connected to " + this.baseURI); _connectionListener(status, tunnel, hostname, port, application); } else if ( statusCode == "NetConnection.Connect.Rejected" || statusCode == "NetConnection.Connect.Failed" || statusCode == "NetConnection.Connect.Closed" ) { LOGGER.debug("Failed to connect to " + this.baseURI); status = "FAILED"; _connectionListener(status, tunnel, hostname, port, application); } closeConnection(); } 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]); } public function addConnectionSuccessListener(listener:Function):void { _connectionListener = listener; } } }
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.main.model
{
import flash.events.NetStatusEvent;
import flash.events.TimerEvent;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.utils.Timer;
import flash.utils.Dictionary;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
[Bindable]
/**
* Test RTMP port.
*
* @author Thijs Triemstra ( info@collab.nl )
*/
public class PortTest
{
private static const LOGGER:ILogger = getClassLogger(PortTest);
/**
* Connect using rtmp or rtmpt.
*/
private var tunnel: Boolean;
/**
* RTMP hostname.
*/
private var hostname : String;
/**
* RTMP port.
*/
public var port : String;
/**
* RTMP port.
*/
public var portName : String = "Default";
/**
* RTMP application.
*/
private var application : String;
/**
* Base RTMP URI.
*/
private var baseURI : String;
/**
* RTMP connection.
*/
public var nc : NetConnection;
/**
* Connection status.
*/
public var status : String;
private var _connectionListener:Function;
/**
* Timer to control timeout of connection test
*/
private var testTimeout:Number = 0;
/**
* Timer to control timeout of connection test
*/
private var connectionTimer:Timer;
private var closeConnectionTimer:Timer;
/**
* Set default encoding to AMF0 so FMS also understands.
*/
NetConnection.defaultObjectEncoding = ObjectEncoding.AMF0;
/**
* Create new port test and connect to the RTMP server.
*
* @param protocol
* @param hostname
* @param port
* @param application
* @testTimeout timeout of test in milliseconds
*/
public function PortTest( tunnel : Boolean,
hostname : String = "",
port : String = "",
application : String = "",
testTimeout : Number = 10000) {
this.tunnel = tunnel;
this.hostname = hostname;
this.application = application;
this.testTimeout = testTimeout;
if ( port.length > 0 ) {
this.portName = port;
this.port = ":" + port;
} else {
this.port = port;
}
// Construct URI.
if (tunnel) {
this.baseURI = "rtmpt://" + this.hostname + "/" + this.application;
} else {
this.baseURI = "rtmp://" + this.hostname + this.port + "/" + this.application;
}
}
/**
* Start connection.
*/
public function connect():void {
nc = new NetConnection();
nc.client = this;
nc.proxyType = "best";
nc.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
// connect to server
try {
var logData:Object = UsersUtil.initLogData();
logData.connection = this.baseURI;
logData.tags = ["initialization", "port-test", "connection"];
logData.message = "Port testing connection.";
LOGGER.info(JSON.stringify(logData));
connectionTimer = new Timer(testTimeout, 1);
connectionTimer.addEventListener(TimerEvent.TIMER, connectionTimeout);
connectionTimer.start();
var curTime:Number = new Date().getTime();
// Create connection with the server.
nc.connect( this.baseURI, "portTestMeetingId-" + curTime, "portTestDummyUserId-" + curTime);
status = "Connecting...";
} catch( e : ArgumentError ) {
// Invalid parameters.
status = "ERROR: " + e.message;
}
}
/**
* Method called when connection timed out
*/
public function connectionTimeout (e:TimerEvent) : void {
var logData:Object = UsersUtil.initLogData();
logData.connection = this.baseURI;
logData.tags = ["initialization", "port-test", "connection"];
logData.message = "Port testing connection timedout.";
LOGGER.info(JSON.stringify(logData));
status = "FAILED";
_connectionListener(status, tunnel, hostname, port, application);
closeConnection();
}
/**
* Close connection.
*/
private function close():void {
var dc:Dictionary = new Dictionary(true);
nc.client = dc;
// Remove listener.
nc.removeEventListener( NetStatusEvent.NET_STATUS, netStatus );
// Close the NetConnection.
nc.close();
}
private function closeConnection():void {
closeConnectionTimer = new Timer(100, 1);
closeConnectionTimer.addEventListener(TimerEvent.TIMER, closeConnectionTimerHandler);
closeConnectionTimer.start();
}
private function closeConnectionTimerHandler (e:TimerEvent) : void {
var logData:Object = UsersUtil.initLogData();
logData.connection = this.baseURI;
logData.tags = ["initialization", "port-test", "connection"];
logData.message = "Closing port testing connection.";
LOGGER.info(JSON.stringify(logData));
close();
}
/**
* Catch NetStatusEvents.
*
* @param event
* */
protected function netStatus(event : NetStatusEvent):void {
//Stop timeout timer when connected/rejected
connectionTimer.stop();
var info : Object = event.info;
var statusCode : String = info.code;
var logData:Object = UsersUtil.initLogData();
logData.connection = this.baseURI;
logData.tags = ["initialization", "port-test", "connection"];
if ( statusCode == "NetConnection.Connect.Success" ) {
status = "SUCCESS";
logData.message = "Port test successfully connected.";
LOGGER.info(JSON.stringify(logData));
_connectionListener(status, tunnel, hostname, port, application);
} else if ( statusCode == "NetConnection.Connect.Rejected" ||
statusCode == "NetConnection.Connect.Failed" ||
statusCode == "NetConnection.Connect.Closed" ) {
logData.message = "Port test failed to connect.";
LOGGER.info(JSON.stringify(logData));
status = "FAILED";
_connectionListener(status, tunnel, hostname, port, application);
}
//closeConnection();
}
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]);
}
public function addConnectionSuccessListener(listener:Function):void {
_connectionListener = listener;
}
}
}

View File

@ -9,7 +9,7 @@ package org.bigbluebutton.main.model.modules
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.as3commons.logging.util.jsonXify;
@ -59,18 +59,29 @@ package org.bigbluebutton.main.model.modules
var result:Object = JSON.parse(e.target.data);
LOGGER.debug("Enter response = {0}", [jsonXify(result)]);
var logData:Object = UsersUtil.initLogData
var returncode:String = result.response.returncode;
if (returncode == 'FAILED') {
LOGGER.error("Enter API call FAILED = {0}", [jsonXify(result)]);
logData.tags = ["initialization"];
logData.message = "Enter API call failed.";
LOGGER.info(JSON.stringify(logData));
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new MeetingNotFoundEvent(result.response.logoutURL));
} else if (returncode == 'SUCCESS') {
LOGGER.debug("Enter API call SUCESS = {0}", [jsonXify(result)]);
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);
}

View File

@ -32,7 +32,7 @@ package org.bigbluebutton.main.model.modules
import org.bigbluebutton.main.events.ModuleLoadEvent;
import org.bigbluebutton.main.events.PortTestEvent;
import org.bigbluebutton.main.events.UserServicesEvent;
import org.bigbluebutton.main.model.ConfigParameters;
import org.bigbluebutton.main.model.ConfigParameters;
public class ModulesDispatcher
{
@ -111,31 +111,11 @@ package org.bigbluebutton.main.model.modules
dispatcher.dispatchEvent(evt);
}
public function sendTunnelingFailedEvent(server: String, app: String):void{
var logData:Object = new Object();
logData.server = server;
logData.app = app;
logData.userId = meetingInfo.userId;
logData.username = meetingInfo.username;
logData.meetingName = meetingInfo.meetingName;
logData.meetingId = meetingInfo.meetingId;
LOGGER.fatal("Cannot connect to Red5 using RTMP and RTMPT {0}", [jsonXify(logData)]);
JSLog.critical("Cannot connect to Red5 using RTMP and RTMPT", logData);
public function sendTunnelingFailedEvent(server: String, app: String):void{
dispatcher.dispatchEvent(new PortTestEvent(PortTestEvent.TUNNELING_FAILED));
}
public function sendPortTestSuccessEvent(port:String, host:String, tunnel:Boolean, app:String):void{
var logData:Object = new Object();
logData.port = port;
logData.server = host;
logData.tunnel = tunnel;
logData.app = app;
logData.userId = meetingInfo.userId;
logData.username = meetingInfo.username;
logData.meetingName = meetingInfo.meetingName;
logData.meetingId = meetingInfo.meetingId;
JSLog.debug("Successfully connected on test connection.", logData);
var portEvent:PortTestEvent = new PortTestEvent(PortTestEvent.PORT_TEST_SUCCESS);
portEvent.port = port;

View File

@ -21,7 +21,8 @@ package org.bigbluebutton.main.model.modules
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.main.model.ConferenceParameters;
import org.bigbluebutton.main.model.PortTestProxy;
import org.bigbluebutton.main.model.PortTestProxy;
import org.bigbluebutton.core.UsersUtil;
public class ModulesProxy {
private static const LOGGER:ILogger = getClassLogger(ModulesProxy);
@ -43,7 +44,12 @@ package org.bigbluebutton.main.model.modules
}
public function portTestSuccess(tunnel:Boolean):void {
LOGGER.debug("Successfully tested connection to server. isTunnelling=" + tunnel);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["initialization"];
logData.tunnel = tunnel;
logData.message = "Successfully tested connection to server.";
LOGGER.info(JSON.stringify(logData));
modulesManager.useProtocol(tunnel);
modulesManager.startUserServices();
}

View File

@ -1,4 +1,4 @@
/**
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).

View File

@ -27,7 +27,7 @@ package org.bigbluebutton.main.model.users
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.as3commons.logging.util.jsonXify;
@ -80,62 +80,74 @@ package org.bigbluebutton.main.model.users
}
private function ioErrorHandler(event:IOErrorEvent):void {
LOGGER.error("ioErrorHandler: {0}", [event]);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["initialization"];
logData.message = "IOError calling ENTER api.";
LOGGER.error(JSON.stringify(logData));
var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT);
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(e);
}
private function handleComplete(e:Event):void {
var result:Object = JSON.parse(e.target.data);
LOGGER.debug("Enter response = {0}" + [jsonXify(result)]);
var result:Object = JSON.parse(e.target.data);
var returncode:String = result.response.returncode;
if (returncode == 'FAILED') {
LOGGER.error("Join FAILED = {0}", [jsonXify(result)]);
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new MeetingNotFoundEvent(result.response.logoutURL));
} else if (returncode == 'SUCCESS') {
LOGGER.debug("Join SUCESS = {0}", [jsonXify(result)]);
var response:Object = new Object();
response.username = result.response.fullname;
response.conference = result.response.conference;
response.conferenceName = result.response.confname;
response.externMeetingID = result.response.externMeetingID;
response.meetingID = result.response.meetingID;
response.isBreakout = result.response.isBreakout;
response.externUserID = result.response.externUserID;
response.internalUserId = result.response.internalUserID;
response.role = result.response.role;
response.room = result.response.room;
response.authToken = result.response.authToken;
response.record = result.response.record;
response.allowStartStopRecording = result.response.allowStartStopRecording;
response.webvoiceconf = result.response.webvoiceconf;
response.dialnumber = result.response.dialnumber;
response.voicebridge = result.response.voicebridge;
response.mode = result.response.mode;
response.welcome = result.response.welcome;
response.logoutUrl = result.response.logoutUrl;
response.defaultLayout = result.response.defaultLayout;
response.avatarURL = result.response.avatarURL
var logData:Object = UsersUtil.initLogData();
logData.tags = ["initialization"];
var returncode:String = result.response.returncode;
if (returncode == 'FAILED') {
logData.message = "Calling ENTER api failed.";
LOGGER.info(JSON.stringify(logData));
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new MeetingNotFoundEvent(result.response.logoutURL));
} else if (returncode == 'SUCCESS') {
logData.message = "Calling ENTER api succeeded.";
LOGGER.info(JSON.stringify(logData));
var response:Object = new Object();
response.username = result.response.fullname;
response.conference = result.response.conference;
response.conferenceName = result.response.confname;
response.externMeetingID = result.response.externMeetingID;
response.meetingID = result.response.meetingID;
response.isBreakout = result.response.isBreakout;
response.externUserID = result.response.externUserID;
response.internalUserId = result.response.internalUserID;
response.role = result.response.role;
response.room = result.response.room;
response.authToken = result.response.authToken;
response.record = result.response.record;
response.allowStartStopRecording = result.response.allowStartStopRecording;
response.webvoiceconf = result.response.webvoiceconf;
response.dialnumber = result.response.dialnumber;
response.voicebridge = result.response.voicebridge;
response.mode = result.response.mode;
response.welcome = result.response.welcome;
response.logoutUrl = result.response.logoutUrl;
response.defaultLayout = result.response.defaultLayout;
response.avatarURL = result.response.avatarURL
if (result.response.hasOwnProperty("modOnlyMessage")) {
response.modOnlyMessage = result.response.modOnlyMessage;
MeetingModel.getInstance().modOnlyMessage = response.modOnlyMessage;
}
if (result.response.hasOwnProperty("modOnlyMessage")) {
response.modOnlyMessage = result.response.modOnlyMessage;
MeetingModel.getInstance().modOnlyMessage = response.modOnlyMessage;
}
response.customdata = new Object();
response.customdata = new Object();
if (result.response.customdata) {
var cdata:Array = result.response.customdata as Array;
for each (var item:Object in cdata) {
for (var id:String in item) {
var value:String = item[id] as String;
response.customdata[id] = value;
}
}
}
if (result.response.customdata) {
var cdata:Array = result.response.customdata as Array;
for each (var item:Object in cdata) {
for (var id:String in item) {
var value:String = item[id] as String;
response.customdata[id] = value;
}
}
}
UsersModel.getInstance().me = new MeBuilder(response.internalUserId, response.username).withAvatar(response.avatarURL)
.withExternalId(response.externUserID).withToken(response.authToken)

View File

@ -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,402 +40,450 @@ 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();
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 maxConnectAttempt:int = 2;
private var connectAttemptCount:int = 0;
private var connectAttemptTimeout:Number = 5000;
private var connectionTimer:Timer;
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;
}
private var numNetworkChangeCount:int = 0;
private var _validateTokenTimer:Timer = null;
private var bbbAppsUrl: String = null;
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;
public function NetConnectionDelegate():void {
dispatcher = new Dispatcher();
_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 );
}
}
}
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 = 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 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
}
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 = new Object();
logData.user = UsersUtil.getUserData();
JSLog.critical("Validate auth token timed out.", logData);
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;
if (tokenValid) {
authenticated = true;
} else {
dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
}
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);
}
}
/**
* 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 );
public function get connection():NetConnection {
return _netConnection;
}
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) {
uri = "rtmpt://" + result.server + "/" + result.app + "/" + confParams.room;
} else {
uri = "rtmp://" + result.server + ":1935/" + result.app + "/" + confParams.room;
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]);
}
}
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;
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
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;
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
_validateTokenTimer = new Timer(10000, 1);
_validateTokenTimer.addEventListener(TimerEvent.TIMER, validataTokenTimerHandler);
_validateTokenTimer.start();
}
private function stopValidateTokenTimer():void {
if (_validateTokenTimer != null && _validateTokenTimer.running) {
_validateTokenTimer.stop();
_validateTokenTimer = null;
}
}
private function handleValidateAuthTokenTimedOut(msg: Object):void {
stopValidateTokenTimer();
switch (statusCode) {
case "NetConnection.Connect.Success":
numNetworkChangeCount = 0;
JSLog.debug("Successfully connected to BBB App.", logData);
validateToken();
break;
case "NetConnection.Connect.Failed":
LOGGER.error(":Connection to viewers application failed...even when tunneling");
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":
LOGGER.debug(":viewers application not found on server");
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 {
LOGGER.error("Security error - {0}", [event.text]);
sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
}
protected function netIOError(event: IOErrorEvent):void {
LOGGER.error("Input/output error - {0}", [event.text]);
sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
}
protected function netASyncError(event: AsyncErrorEvent):void {
LOGGER.debug("Asynchronous code error - {0}", [event.toString()]);
sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
}
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;
}
}
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 logData:Object = UsersUtil.initLogData();
logData.tags = ["apps", "connected"];
logData.tokenValid = tokenValid;
logData.status = "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());
}
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();
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));
connectAttemptCount++;
connectionTimer = new Timer(connectAttemptTimeout, 1);
connectionTimer.addEventListener(TimerEvent.TIMER, connectionTimeout);
connectionTimer.start();
_netConnection.connect(bbbAppsUrl, 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();
}
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;
//Stop timeout timer when connected/rejected
if (connectionTimer != null && connectionTimer.running) {
connectionTimer.stop();
connectionTimer = null;
}
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps", "connection"];
switch (statusCode) {
case "NetConnection.Connect.Success":
numNetworkChangeCount = 0;
connectAttemptCount = 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.";
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":
logData.message = "bbb-app not found.";
LOGGER.info(JSON.stringify(logData));
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 {
var logData:Object = UsersUtil.initLogData();
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 {
var logData:Object = UsersUtil.initLogData();
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);
}
private function sendConnectionFailedEvent(reason:String):void{
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps", "connection"];
if (this.logoutOnUserCommand) {
logData.reason = "User requested.";
logData.user = UsersUtil.getUserData();
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
logData.reason = reason;
logData.user = UsersUtil.getUserData();
logData.message = "User disconnected from BBB App.";
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;
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);
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.user = UsersUtil.getUserData();
logData.message = "User has been ejected from meeting.";
LOGGER.info(JSON.stringify(logData));
reason = ConnectionFailedEvent.USER_EJECTED_FROM_MEETING;
var cfe:ConnectionFailedEvent = new ConnectionFailedEvent(reason);
dispatcher.dispatchEvent(cfe);
} else {
logData.message = "Connection failed event - " + reason;
LOGGER.info(JSON.stringify(logData));
var e:ConnectionFailedEvent = new ConnectionFailedEvent(reason);
dispatcher.dispatchEvent(e);
}
LOGGER.debug("Connection failed event - " + reason);
var e:ConnectionFailedEvent = new ConnectionFailedEvent(reason);
dispatcher.dispatchEvent(e);
}
}
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]);
}
}
}

View File

@ -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);
}
}
}

View File

@ -39,7 +39,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import com.asfusion.mate.events.Dispatcher;
import flash.ui.Keyboard;
import org.bigbluebutton.core.UsersUtil;
import mx.controls.sliderClasses.Slider;
import mx.events.CloseEvent;
import mx.events.SliderEvent;
@ -100,7 +100,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function reInitialize():void {
my_nc = new NetConnection();
my_nc.proxyType = "best";
my_nc.proxyType = "best";
my_nc.connect(null);
nsStream = new NetStream(my_nc);
if (mic != null) {
@ -127,14 +127,21 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
audioMicLevelDetected = 0;
}
private function micStatusEventHandler(event:StatusEvent):void {
private function micStatusEventHandler(event:StatusEvent):void {
var logData:Object = UsersUtil.initLogData();
switch(event.code) {
case "Microphone.Muted":
LOGGER.debug("Access to microphone has been denied.");
case "Microphone.Muted":
logData.tags = ["voice", "flash"];
logData.message = "Access to microphone has been denied.";
LOGGER.info(JSON.stringify(logData));
statusText.text = "You did not allow Flash to access your mic.";
break;
case "Microphone.Unmuted":
LOGGER.debug("Access to the microphone has been allowed.");
logData.tags = ["voice", "flash"];
logData.message = "Access to the microphone has been allowed.";
LOGGER.info(JSON.stringify(logData));
// Comment these next 2-lines. We don't want the user hearing audio
// while testing mic levels. (richard mar 26, 2014)
// mic.setLoopBack(true);
@ -155,7 +162,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
micActivityTimer.start();
}
private function onCreationComplete():void {
private function onCreationComplete():void {
LOGGER.debug("onCreationComplete. Seeting state to [flashMicSettingsTest]");
microphoneList = Media.getMicrophoneNames();
setupForMicLoopbackTest();
@ -252,7 +259,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function onCancelClicked():void {
LOGGER.debug("onCancelClicked closing popup");
cleanUp();
stopEchoTest();
var dispatcher:Dispatcher = new Dispatcher();
@ -292,7 +298,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function yesButtonClicked():void {
LOGGER.debug("Echo test passed.");
var logData:Object = UsersUtil.initLogData();
logData.tags = ["voice"];
logData.message = "Echo test passed.";
LOGGER.info(JSON.stringify(logData));
cleanUp();
dispatchEvent(new FlashEchoTestHasAudioEvent());
var dispatcher:Dispatcher = new Dispatcher();
@ -301,7 +311,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function noButtonClicked():void {
LOGGER.debug("Echo test failed.");
var logData:Object = UsersUtil.initLogData();
logData.tags = ["voice"];
logData.message = "Echo test failed.";
LOGGER.info(JSON.stringify(logData));
dispatchEvent(new FlashEchoTestNoAudioEvent());
testMicrophoneLoopback();
setupForMicLoopbackTest();

View File

@ -11,6 +11,7 @@ terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
@ -119,6 +120,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.users.views.BreakoutRoomSettings;
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.core.UsersUtil;
private static const LOGGER:ILogger = getClassLogger(MainApplicationShell);
@ -222,14 +224,25 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function handleApplicationVersionEvent(event:AppVersionEvent):void {
var logData:Object = UsersUtil.initLogData();
if (event.configLocaleVersion == true) {
receivedConfigLocaleVer = true;
appVersion = event.appVersion;
localeVersion = event.localeVersion;
logData.localeVersion = localeVersion;
logData.tags = ["locale"];
logData.message = "Received locale version from config.xml";
LOGGER.info(JSON.stringify(logData));
LOGGER.debug("Received locale version fron config.xml");
} else {
receivedResourceLocaleVer = true;
LOGGER.debug("Received locale version fron locale file.");
logData.tags = ["locale"];
logData.message = "Received locale version from locale file";
LOGGER.info(JSON.stringify(logData));
}
if (receivedConfigLocaleVer && receivedResourceLocaleVer) {
@ -252,11 +265,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
LOGGER.debug("Switching to full screen");
/* Do something specific here if we switched to full screen mode. */
} else {
LOGGER.debug("Switching to normal screen");
/* Do something specific here if we switched to normal mode. */
}
}
@ -286,16 +297,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function toggleFullScreen():void{
LOGGER.debug("Toggling fullscreen");
try {
switch (stage.displayState) {
case StageDisplayState.FULL_SCREEN:
LOGGER.debug("full screen mode");
// If already in full screen mode, switch to normal mode.
stage.displayState = StageDisplayState.NORMAL;
break;
default:
LOGGER.debug("Normal screen mode");
// If not in full screen mode, switch to full screen mode.
stage.displayState = StageDisplayState.FULL_SCREEN;
break;
@ -309,7 +317,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
// this is a terrible place for these checks because this function runs 4 times on startup
if (BBB.initConnectionManager().isTunnelling) {
isTunneling = true;
globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT, ResourceUtil.getInstance().getString("bbb.clientstatus.tunneling.title"), ResourceUtil.getInstance().getString("bbb.clientstatus.tunneling.message")));
globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.tunneling.title"),
ResourceUtil.getInstance().getString("bbb.clientstatus.tunneling.message"),
'bbb.clientstatus.tunneling'));
}
versionCheck();
@ -331,7 +342,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
if ((browserVersion[0].toString().toLowerCase() == "chrome" && browserVersion[1] < xml.@chrome) || browserVersion[0].toString().toLowerCase() == "firefox" && browserVersion[1] < xml.@firefox) {
globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.browser.title"),
ResourceUtil.getInstance().getString("bbb.clientstatus.browser.message", [browserVersion[0]+" "+browserVersion[1]])));
ResourceUtil.getInstance().getString("bbb.clientstatus.browser.message", [browserVersion[0]+" "+browserVersion[1]]),
'bbb.clientstatus.browser.message'));
}
//find flash version
@ -341,7 +353,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
((flashVersion.os != 'LNX' || browserVersion[0].toString().toLowerCase() == "chrome") && flashVersion.major < xml.@flash)) {
globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.flash.title"),
ResourceUtil.getInstance().getString("bbb.clientstatus.flash.message", [flashVersion.major+"."+flashVersion.minor+"."+flashVersion.build])));
ResourceUtil.getInstance().getString("bbb.clientstatus.flash.message", [flashVersion.major+"."+flashVersion.minor+"."+flashVersion.build]),
'bbb.clientstatus.flash.message'));
}
}
@ -377,8 +390,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
Alert.okLabel ="OK";
var version:String = "old-locales";
version = ResourceUtil.getInstance().getString('bbb.mainshell.locale.version');
LOGGER.debug("Locale from config={0}, from locale file={1}", [localeVersion, version]);
var logData:Object = UsersUtil.initLogData();
logData.configVersion = localeVersion;
logData.localeVersion = version;
logData.locale = ResourceUtil.getInstance().getCurrentLanguageCode();
logData.tags = ["locale"];
logData.message = "Loaded locale.";
LOGGER.info(JSON.stringify(logData));
if ((version == "old-locales") || (version == "") || (version == null)) {
wrongLocaleVersion();
} else {
@ -630,7 +650,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function onFooterLinkClicked(e:TextEvent):void{
LOGGER.debug("Clicked on link[{0}] from footer", [e.text]);
if (ExternalInterface.available) {
ExternalInterface.call("chatLinkClicked", e.text);
}

View File

@ -187,8 +187,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function logFlashPlayerCapabilities():void {
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["initialization"];
logData.capabilities = getFlashPlayerCapabilities();
logData.message = "Flash Player Capabilities.";
LOGGER.info(JSON.stringify(logData));

View File

@ -94,7 +94,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
messages.push(obj);
showNotification();
LOGGER.warn("ClientNotification:" + e.title + " " + e.message);
var logData:Object = {};
logData.type = "ClientNotification";
logData.logCode = e.logCode;
logData.message = e.message;
logData.title = e.title;
LOGGER.warn(JSON.stringify(logData));
}
private function showNotification():void {
@ -102,7 +108,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
visible = includeInLayout = true;
if (hideTimer.running) hideTimer.reset();
hideTimer.start()
hideTimer.start();
if (!notification) {
notification = ToolTipManager.createToolTip(ResourceUtil.getInstance().getString("bbb.clientstatus.notification"), 100, 100, "errorTipAbove", this) as ToolTip;

View File

@ -101,13 +101,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
userClosed = true;
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.reason = "User requested.";
logData.user = UsersUtil.getUserData();
logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test passed.";
JSLog.info("WebRtc Echo test passed.", logData);
LOGGER.info(JSON.stringify(logData));
setCurrentState("connecting");
@ -120,11 +117,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function noButtonClicked():void {
userClosed = true;
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.reason = "User requested.";
logData.user = UsersUtil.getUserData();
logData.message = "WebRtc Echo test failed.";
logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test failed.";
LOGGER.info(JSON.stringify(logData));
var dispatcher:Dispatcher = new Dispatcher();
@ -190,9 +186,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
}
private function webRTCCallStarted():void {
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.reason = "User requested.";
logData.user = UsersUtil.getUserData();
logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc call started.";
LOGGER.info(JSON.stringify(logData));

View File

@ -16,16 +16,16 @@
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.layout.model {
import flash.utils.Dictionary;
import flexlib.mdi.containers.MDICanvas;
import flexlib.mdi.containers.MDIWindow;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Role;
import org.bigbluebutton.core.managers.UserManager;
package org.bigbluebutton.modules.layout.model {
import flash.utils.Dictionary;
import flexlib.mdi.containers.MDICanvas;
import flexlib.mdi.containers.MDIWindow;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Role;
import org.bigbluebutton.core.managers.UserManager;
public class LayoutDefinition {
@ -92,8 +92,11 @@ package org.bigbluebutton.modules.layout.model {
} else if (hasPresenterLayout) {
return _layoutsPerRole[Role.PRESENTER];
} else {
LOGGER.error("There's no layout that fits the participants profile");
//trace(LOG + "getMyLayout There's no layout that fits the participants profile");
var logData:Object = UsersUtil.initLogData();
logData.tags = ["layout"];
logData.message = "There's no layout that fits the participants profile.";
LOGGER.error(JSON.stringify(logData));
return null;
}
}

View File

@ -148,18 +148,18 @@ package org.bigbluebutton.modules.phone.managers {
var info : Object = event.info;
var statusCode : String = info.code;
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
switch (statusCode) {
case "NetConnection.Connect.Success":
numNetworkChangeCount = 0;
LOGGER.debug("Connection success");
JSLog.debug("Successfully connected to BBB Voice", logData);
logData.tags = ["voice", "flash"];
logData.message = "Connection success.";
LOGGER.info(JSON.stringify(logData));
handleConnectionSuccess();
break;
case "NetConnection.Connect.Failed":
JSLog.error("Failed to connect to BBB Voice", logData);
logData.tags = ["voice", "flash"];
logData.message = "NetConnection.Connect.Failed from bbb-voice";
LOGGER.info(JSON.stringify(logData));
handleConnectionFailed();
@ -167,13 +167,14 @@ package org.bigbluebutton.modules.phone.managers {
case "NetConnection.Connect.NetworkChange":
numNetworkChangeCount++;
if (numNetworkChangeCount % 20 == 0) {
logData.tags = ["voice", "flash"];
logData.message = "Detected network change on bbb-voice";
logData.numNetworkChangeCount = numNetworkChangeCount;
LOGGER.info(JSON.stringify(logData));
}
break;
case "NetConnection.Connect.Closed":
JSLog.debug("Disconnected from BBB Voice", logData);
logData.tags = ["voice", "flash"];
logData.message = "Disconnected from BBB Voice";
LOGGER.info(JSON.stringify(logData));
handleConnectionClosed();

View File

@ -277,12 +277,11 @@
public function handleFlashCallConnectedEvent(event:FlashCallConnectedEvent):void {
LOGGER.debug("handling FlashCallConnectedEvent, current state: {0}", [state]);
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["voice", "flash"];
switch (state) {
case CALLING_INTO_CONFERENCE:
JSLog.info("Successfully joined the voice conference.", logData);
logData.message = "Successfully joined the voice conference";
LOGGER.info(jsonXify(logData));
state = IN_CONFERENCE;
@ -290,7 +289,6 @@
streamManager.callConnected(event.playStreamName, event.publishStreamName, event.codec, event.listenOnlyCall);
break;
case CONNECTING_TO_LISTEN_ONLY_STREAM:
JSLog.info("Successfully connected to the listen only stream.", logData);
logData.message = "Successfully connected to the listen only stream.";
LOGGER.info(jsonXify(logData));
state = ON_LISTEN_ONLY_STREAM;
@ -299,7 +297,6 @@
break;
case CALLING_INTO_ECHO_TEST:
state = IN_ECHO_TEST;
JSLog.info("Successfully called into the echo test application.", logData);
logData.message = "Successfully called into the echo test application.";
logData.publishStreamName = event.publishStreamName;
logData.playStreamName = event.playStreamName;
@ -317,8 +314,8 @@
}
public function handleFlashCallDisconnectedEvent(event:FlashCallDisconnectedEvent):void {
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["voice", "flash"];
LOGGER.debug("Flash call disconnected, current state: {0}", [state]);
switch (state) {
@ -328,14 +325,12 @@
break;
case ON_LISTEN_ONLY_STREAM:
state = INITED;
JSLog.info("Flash user left the listen only stream.", logData);
logData.message = "Flash user left the listen only stream.";
LOGGER.info(jsonXify(logData));
dispatcher.dispatchEvent(new FlashLeftVoiceConferenceEvent());
break;
case IN_ECHO_TEST:
state = INITED;
JSLog.info("Flash echo test stopped.", logData);
logData.message = "Flash echo test stopped.";
LOGGER.info(jsonXify(logData));
@ -347,8 +342,6 @@
break;
case CALLING_INTO_ECHO_TEST:
state = INITED;
JSLog.error("Unsuccessfully called into the echo test application.", logData);
logData.message = "Unsuccessfully called into the echo test application.";
LOGGER.info(jsonXify(logData));
dispatcher.dispatchEvent(new FlashEchoTestFailedEvent());

View File

@ -14,7 +14,6 @@ package org.bigbluebutton.modules.phone.managers
import org.as3commons.logging.util.jsonXify;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.api.JSAPI;
import org.bigbluebutton.main.api.JSLog;
import org.bigbluebutton.main.events.ClientStatusEvent;
import org.bigbluebutton.main.model.users.AutoReconnect;
import org.bigbluebutton.modules.phone.PhoneModel;
@ -32,7 +31,7 @@ package org.bigbluebutton.modules.phone.managers
public class WebRTCCallManager
{
private static const LOGGER:ILogger = getClassLogger(WebRTCCallManager);
private static const LOGGER:ILogger = getClassLogger(WebRTCCallManager);
private const MAX_RETRIES:Number = 3;
private var browserType:String = "unknown";
@ -60,7 +59,8 @@ package org.bigbluebutton.modules.phone.managers
if (options.useWebRTCIfAvailable && !isWebRTCSupported()) {
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.webrtc.title"),
ResourceUtil.getInstance().getString("bbb.clientstatus.webrtc.message")));
ResourceUtil.getInstance().getString("bbb.clientstatus.webrtc.message"),
'bbb.clientstatus.webrtc.title'));
}
usingWebRTC = checkIfToUseWebRTC();
@ -135,7 +135,8 @@ package org.bigbluebutton.modules.phone.managers
if(reconnecting) {
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.reestablished"),
ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.reestablished")));
ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.reestablished"),
'bbb.webrtcWarning.connection.reestablished'));
reconnecting = false;
}
}
@ -150,8 +151,12 @@ package org.bigbluebutton.modules.phone.managers
}
public function handleJoinVoiceConferenceCommand(event:JoinVoiceConferenceCommand):void {
LOGGER.debug("handleJoinVoiceConferenceCommand - usingWebRTC: " + usingWebRTC + ", event.mic: " + event.mic);
var logData:Object = UsersUtil.initLogData();
logData.usingWebRTC = usingWebRTC;
logData.eventMic = event.mic;
logData.message = "handleJoinVoiceConferenceCommand - usingWebRTC:";
LOGGER.info(JSON.stringify(logData));
if (!usingWebRTC || !event.mic) return;
if (options.skipCheck || echoTestDone) {
@ -200,28 +205,34 @@ package org.bigbluebutton.modules.phone.managers
errorString = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.unknown", [event.errorCode]);
}
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
logData.user.reason = errorString;
var logData:Object = UsersUtil.initLogData();
logData.user.reason = errorString;
logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test failed.";
JSLog.warn("WebRtc Echo test failed.", logData);
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"), ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]), errorString);
logData.errorEvent = event;
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"),
ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]),
errorString,
'bbb.webrtcWarning webRTCEchoTestFailedEvent');
}
public function handleWebRTCEchoTestEndedUnexpectedly():void {
model.state = Constants.INITED;
var errorString:String = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.endedunexpectedly");
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
logData.user.reason = errorString;
var logCode:String = "bbb.webrtcWarning.failedError.endedunexpectedly";
var errorString:String = ResourceUtil.getInstance().getString(logCode);
var logData:Object = UsersUtil.initLogData();
logData.user.reason = errorString;
logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test ended unexpectedly.";
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"), ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]), errorString);
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"),
ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]),
errorString,
logCode);
}
public function handleWebRTCCallFailedEvent(event:WebRTCCallEvent):void {
@ -233,7 +244,8 @@ package org.bigbluebutton.modules.phone.managers
reconnecting = true;
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.dropped"),
ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.reconnecting")));
ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.reconnecting"),
'bbb.webrtcWarning.connection.dropped,reconnecting'));
reconnect.onDisconnect(joinVoiceConference, []);
}
else {
@ -256,26 +268,32 @@ package org.bigbluebutton.modules.phone.managers
errorString = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.unknown", [event.errorCode]);
}
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
logData.user.reason = errorString;
var logData:Object = UsersUtil.initLogData();
logData.tags = ["voice", "webrtc"];
logData.errorEvent = event;
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"), ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]), errorString);
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"),
ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]),
errorString,
'bbb.webrtcWarning.failedError');
}
}
}
public function handleWebRTCMediaFailedEvent():void {
model.state = Constants.INITED;
var errorString:String = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.mediamissing");
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
logData.user.reason = errorString;
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"), ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]), errorString);
var logCode:String = "bbb.webrtcWarning.failedError.mediamissing";
var errorString:String = ResourceUtil.getInstance().getString(logCode);
var logData:Object = UsersUtil.initLogData();
logData.user.reason = errorString;
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"),
ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]),
errorString,
logCode);
}
private var popUpDelayTimer:Timer = new Timer(100, 1);
@ -297,7 +315,7 @@ package org.bigbluebutton.modules.phone.managers
}
}
private function sendWebRTCAlert(title:String, message:String, error:String):void {
private function sendWebRTCAlert(title:String, message:String, error:String, logCode:String):void {
/**
* There is a bug in Flex SDK 4.14 where the screen stays blurry if a
* pop-up is opened from another pop-up. I delayed the second open to
@ -308,9 +326,15 @@ package org.bigbluebutton.modules.phone.managers
Alert.show(message, title, Alert.YES | Alert.NO, null, handleCallFailedUserResponse, null, Alert.YES);
});
popUpDelayTimer.start();
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.FAIL_MESSAGE_EVENT, title, error));
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.FAIL_MESSAGE_EVENT, title, error, logCode));
LOGGER.warn("WebRTCAlert:" + title + " " + error + " " + message);
var logData:Object = UsersUtil.initLogData();
logData.type = "WebRTCAlert";
logData.title = title;
logData.error = error;
logData.message = message;
logData.logCode = logCode;
LOGGER.warn(JSON.stringify(logData));
}
}
}

View File

@ -29,13 +29,13 @@ package org.bigbluebutton.modules.present.business
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.present.events.UploadCompletedEvent;
import org.bigbluebutton.modules.present.events.UploadIoErrorEvent;
import org.bigbluebutton.modules.present.events.UploadProgressEvent;
import org.bigbluebutton.modules.present.events.UploadSecurityErrorEvent;
import org.bigbluebutton.modules.present.events.UploadSecurityErrorEvent;
public class FileUploadService {
public static const ID:String = "FileUploadService";
@ -125,8 +125,12 @@ package org.bigbluebutton.modules.present.business
*
*/
private function onUploadIoError(event:IOErrorEvent):void {
if(event.errorID != 2038){ //upload works despite of this error.
LOGGER.error("onUploadIoError text: {0}, errorID: {1}", [event.text, event.errorID]);
if (event.errorID != 2038){ //upload works despite of this error.
var logData:Object = UsersUtil.initLogData();
logData.tags = ["presentation"];
logData.message = "IOError while uploading presentation.";
LOGGER.error(JSON.stringify(logData));
dispatcher.dispatchEvent(new UploadIoErrorEvent());
}
@ -138,8 +142,11 @@ package org.bigbluebutton.modules.present.business
*
*/
private function onUploadSecurityError(event:SecurityErrorEvent) : void {
dispatcher.dispatchEvent(new UploadSecurityErrorEvent());
LOGGER.error("A security error occured while trying to upload the presentation. {0}", [event.toString()]);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["presentation"];
logData.message = "Security error while uploading presentation.";
LOGGER.error(JSON.stringify(logData));
dispatcher.dispatchEvent(new UploadSecurityErrorEvent());
}
}
}

View File

@ -44,7 +44,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<![CDATA[
import mx.collections.ArrayCollection;
import mx.utils.StringUtil;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Images;
@ -158,12 +158,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
if (fileSize > maxFileSizeBytes) {
// Hardcode for now to 30M limit.
// This should be configurable to match what's allowed in nginx. (ralam feb 23, 2010)
LOGGER.debug("File exceeds max limit:({0}>{1})", [fileSize, maxFileSizeBytes]);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["presentation"];
logData.message = "File exceeds max limit.";
logData.fileSizeBytes = fileSize;
logData.maxFileSizeBytes = maxFileSizeBytes;
LOGGER.error(JSON.stringify(logData));
enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert'));
} else {
var presentationName:String = StringUtil.trim(fileToUpload.name);
LOGGER.debug("Uploading file : {0}", [presentationName]);
progBarLbl.visible = true;
lblFileName.enabled = false;

View File

@ -38,9 +38,9 @@ package org.bigbluebutton.modules.screenshare.services.red5
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.screenshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.screenshare.services.red5.WebRTCConnectionEvent;
import org.bigbluebutton.modules.screenshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.screenshare.services.red5.WebRTCConnectionEvent;
public class WebRTCConnection {
private static const LOGGER:ILogger = getClassLogger(Connection);
@ -168,6 +168,12 @@ package org.bigbluebutton.modules.screenshare.services.red5
private function netStatusHandler(event:NetStatusEvent):void {
LOGGER.debug("Connected to [" + getURI() + "]. [" + event.info.code + "]");
var logData:Object = {};
logData.type = "ConnectionStatusChanged";
logData.newStatus = event.info.code;
logData.connection = getURI();
LOGGER.info(JSON.stringify(logData));
if (retryTimer) {
retryCount = 0;
LOGGER.debug("Cancelling retry timer.");
@ -211,7 +217,7 @@ package org.bigbluebutton.modules.screenshare.services.red5
LOGGER.debug(result);
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
LOGGER.error(status);
}
);
@ -257,7 +263,8 @@ package org.bigbluebutton.modules.screenshare.services.red5
break;
case "NetConnection.Connect.NetworkChange":
LOGGER.info("Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
// LOGGER.info("Detected network change. User might be on a wireless and
// temporarily dropped connection. Doing nothing. Just making a note.");
break;
default :

View File

@ -58,6 +58,7 @@
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.screenshare.services.red5.Connection;
import org.bigbluebutton.core.UsersUtil;
private static const LOG:String = "SC::ScreenshareViewWIndow - ";
private static const LOGGER:ILogger = getClassLogger(ScreenshareViewWindow);
@ -116,12 +117,13 @@
maximizeRestoreBtn.tabIndex = baseIndex+2;
closeBtn.tabIndex = baseIndex+3;
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.width = videoWidth;
logData.height = videoHeight;
logData.streamId = streamId;
JSLog.debug(LOG + "onCreationComplete", logData);
LOGGER.info(JSON.stringify(logData));
}
private function onResizeEndEvent(event:MDIWindowEvent):void {
@ -146,12 +148,13 @@
videoHeight = ScreenshareModel.getInstance().height;
streamId = ScreenshareModel.getInstance().streamId;
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.width = videoWidth;
logData.height = videoHeight;
logData.streamId = streamId;
JSLog.debug(LOG + "viewScreenshareStream Chrome", logData);
LOGGER.info(JSON.stringify(logData));
ns = new NetStream(connection.getConnection());
ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
@ -176,11 +179,12 @@
public function onMetaData(info:Object):void{
trace("metadata: width=" + info.width + " height=" + info.height);
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.width = info.width;
logData.height = info.height;
JSLog.debug(LOG + "onMetaData", logData);
LOGGER.info(JSON.stringify(logData));
}
protected function updateButtonsPosition():void {
@ -207,23 +211,25 @@
private function onAsyncError(e:AsyncErrorEvent):void{
LOGGER.debug("asyncerror " + e.toString());
var logData:Object = new Object();
logData.error = e.toString();
JSLog.debug(LOG + "asyncerror ", logData);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.message = "asyncerror";
LOGGER.info(JSON.stringify(logData));
}
private function onNetStatus(e:NetStatusEvent):void{
var logData:Object = new Object();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["screenshare"];
logData.stream = streamId;
switch(e.info.code){
case "NetStream.Play.Start":
LOGGER.debug("NetStream.Publish.Start for broadcast stream " + streamId);
JSLog.debug(LOG + "NetStream.Publish.Start for broadcast stream ", logData);
logData.message = "NetStream.Publish.Start for broadcast stream " + streamId;
LOGGER.info(JSON.stringify(logData));
break;
case "NetStream.Play.UnpublishNotify":
LOGGER.debug("NetStream.Play.UnpublishNotify for broadcast stream " + streamId);
JSLog.debug(LOG + "NetStream.Play.UnpublishNotify for broadcast stream ", logData);
logData.message = "NetStream.Play.UnpublishNotify for broadcast stream " + streamId;
LOGGER.info(JSON.stringify(logData));
stopViewing();
break;
}

View File

@ -180,7 +180,14 @@ package org.bigbluebutton.modules.users.services
}
private function handleUserEjectedFromMeeting(msg: Object):void {
UsersUtil.setUserEjected();
UsersUtil.setUserEjected();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["users"];
logData.status = "user_ejected";
logData.message = "User ejected from meeting.";
LOGGER.info(JSON.stringify(logData));
}
private function handleUserLocked(msg:Object):void {
@ -540,13 +547,12 @@ package org.bigbluebutton.modules.users.services
private function handleUserUnsharedWebcam(msg: Object):void {
var map:Object = JSON.parse(msg.msg);
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
logData.user.webcamStream = map.webcamStream;
logData.user.serverTimestamp = map.serverTimestamp;
JSLog.warn("UserUnsharedWebcam server message", logData);
logData.message = "UserUnsharedWebcam server message";
var logData:Object = UsersUtil.initLogData();
logData.tags = ["webcam"];
logData.message = "UserUnsharedWebcam server message";
logData.user.webcamStream = map.webcamStream;
logData.user.serverTimestamp = map.serverTimestamp;
LOGGER.info(JSON.stringify(logData));
UserManager.getInstance().getConference().unsharedWebcam(map.userId, map.webcamStream);
@ -570,8 +576,6 @@ package org.bigbluebutton.modules.users.services
}
public function participantJoined(joinedUser:Object):void {
LOGGER.info(JSON.stringify(joinedUser));
var user:BBBUser = new BBBUser();
user.userID = joinedUser.userId;
user.name = joinedUser.name;
@ -581,12 +585,7 @@ package org.bigbluebutton.modules.users.services
user.listenOnly = joinedUser.listenOnly;
user.userLocked = joinedUser.locked;
user.avatarURL = joinedUser.avatarURL;
var logData:Object = new Object();
logData.user = user;
logData.message = "User joined.";
LOGGER.info(JSON.stringify(logData));
UserManager.getInstance().getConference().addUser(user);
if (joinedUser.hasStream) {

View File

@ -23,7 +23,7 @@ package org.bigbluebutton.modules.users.services
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ConnectionManager;
import org.bigbluebutton.main.api.JSLog;
import org.bigbluebutton.main.api.JSLog;
public class MessageSender {
private static const LOGGER:ILogger = getClassLogger(MessageSender);
@ -38,7 +38,11 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.userId = userID;
logData.message = "Error occured ejecting user.";
LOGGER.info(JSON.stringify(logData));
},
message
);
@ -50,7 +54,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured querying users.";
LOGGER.info(JSON.stringify(logData));
}
);
}
@ -66,26 +73,34 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured assigning presenter.";
LOGGER.info(JSON.stringify(logData));
},
message
);
}
public function emojiStatus(userID:String, emoji:String):void {
var message:Object = new Object();
message["emojiStatus"] = emoji;
message["userId"] = userID;
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("participants.userEmojiStatus", function(result:String):void
{ // On successful result
}, function(status:String):void
{ // status - On error occurred
LOGGER.error(status);
},
message
);
}
}
public function emojiStatus(userID:String, emoji:String):void {
var message:Object = new Object();
message["emojiStatus"] = emoji;
message["userId"] = userID;
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("participants.userEmojiStatus",
function(result:String):void { // On successful result
}, function(status:String):void { // status - On error occurred
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured setting emoji status.";
LOGGER.info(JSON.stringify(logData));
},
message
);
}
public function createBreakoutRooms(meetingId:String, rooms:Array, durationInMinutes:int, record:Boolean, redirectOnJoin:Boolean):void {
var message:Object = new Object();
@ -102,7 +117,10 @@ package org.bigbluebutton.modules.users.services
// On successful result
}, function(status:String):void
{ // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured creating breakout rooms.";
LOGGER.info(JSON.stringify(logData));
},
jsonMsg
);
@ -121,7 +139,10 @@ package org.bigbluebutton.modules.users.services
_nc.sendMessage("breakoutroom.requestBreakoutJoinUrl", function(result:String):void {
// On successful result
}, function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured requesting breakout room join url.";
LOGGER.info(JSON.stringify(logData));
}, jsonMsg);
}
@ -132,7 +153,10 @@ package org.bigbluebutton.modules.users.services
// On successful result
}, function(status:String):void
{ // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured listen on breakout room.";
LOGGER.info(JSON.stringify(logData));
},
JSON.stringify({meetingId: meetingId, targetMeetingId: targetMeetingId, userId: userId})
);
@ -145,7 +169,10 @@ package org.bigbluebutton.modules.users.services
// On successful result
}, function(status:String):void
{ // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured ending breakout rooms.";
LOGGER.info(JSON.stringify(logData));
},
JSON.stringify({meetingId: meetingId})
);
@ -157,29 +184,33 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured sharing webcam.";
LOGGER.info(JSON.stringify(logData));
},
streamName
);
}
public function removeStream(userID:String, streamName:String):void {
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
JSLog.warn("User stopped sharing webcam event.", logData);
logData.streamId = streamName;
logData.message = "User stopped sharing webcam";
LOGGER.info(JSON.stringify(logData));
var logData:Object = UsersUtil.initLogData();
logData.tags = ["webcam"];
logData.streamId = streamName;
logData.message = "User stopped sharing webcam";
LOGGER.info(JSON.stringify(logData));
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("participants.unshareWebcam",
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured unsharing webcam.";
LOGGER.info(JSON.stringify(logData));
},
streamName
);
@ -192,7 +223,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured getting recording status.";
LOGGER.info(JSON.stringify(logData));
}
); //_netConnection.call
}
@ -208,7 +242,10 @@ package org.bigbluebutton.modules.users.services
// On successful result
}, function(status:String):void
{ // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured querying breakout rooms.";
LOGGER.info(JSON.stringify(logData));
},
jsonMsg
);
@ -225,7 +262,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured change recording status.";
LOGGER.info(JSON.stringify(logData));
},
message
); //_netConnection.call
@ -241,7 +281,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured muting all users.";
LOGGER.info(JSON.stringify(logData));
},
message
);
@ -257,7 +300,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured muting all users except presenter.";
LOGGER.info(JSON.stringify(logData));
},
message
);
@ -274,7 +320,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured muting user.";
LOGGER.info(JSON.stringify(logData));
},
message
);
@ -290,7 +339,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured ejecting user.";
LOGGER.info(JSON.stringify(logData));
},
message
);
@ -305,7 +357,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occuredget room mute state.";
LOGGER.info(JSON.stringify(logData));
}
);
}
@ -319,7 +374,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured getting lock state.";
LOGGER.info(JSON.stringify(logData));
}
);
}
@ -367,7 +425,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured setting user lock status.";
LOGGER.info(JSON.stringify(logData));
},
message
);
@ -421,10 +482,13 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps"];
logData.message = "Error occured saving lock settings.";
LOGGER.info(JSON.stringify(logData));
},
newLockSettings
);
}
}
}
}

View File

@ -85,15 +85,15 @@ package org.bigbluebutton.modules.videoconf.business
}
private function onAsyncError(event:AsyncErrorEvent):void{
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["webcam"];
logData.message = "VIDEO WEBCAM onAsyncError";
LOGGER.error(JSON.stringify(logData));
}
private function onIOError(event:NetStatusEvent):void{
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["webcam"];
logData.message = "VIDEO WEBCAM onIOError";
LOGGER.error(JSON.stringify(logData));
}
@ -112,8 +112,8 @@ package org.bigbluebutton.modules.videoconf.business
private function onNetStatus(event:NetStatusEvent):void{
LOGGER.debug("[{0}] for [{1}]", [event.info.code, _url]);
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
var logData:Object = UsersUtil.initLogData();
logData.tags = ["webcam"];
logData.user.eventCode = event.info.code + "[reconnecting=" + reconnecting + ",reconnect=" + reconnect + "]";
switch(event.info.code){
@ -123,7 +123,6 @@ package org.bigbluebutton.modules.videoconf.business
break;
case "NetStream.Play.Failed":
if (reconnect) {
JSLog.warn("NetStream.Play.Failed from bbb-video", logData);
logData.message = "NetStream.Play.Failed from bbb-video";
LOGGER.info(JSON.stringify(logData));
}
@ -131,7 +130,6 @@ package org.bigbluebutton.modules.videoconf.business
break;
case "NetStream.Play.Stop":
if (reconnect) {
JSLog.warn("NetStream.Play.Stop from bbb-video", logData);
logData.message = "NetStream.Play.Stop from bbb-video";
LOGGER.info(JSON.stringify(logData));
}
@ -162,7 +160,6 @@ package org.bigbluebutton.modules.videoconf.business
}
if (reconnect) {
JSLog.warn("NetConnection.Connect.Failed from bbb-video", logData);
logData.message = "NetConnection.Connect.Failed from bbb-video";
LOGGER.info(JSON.stringify(logData));
}

View File

@ -21,7 +21,7 @@ package org.bigbluebutton.modules.whiteboard.models
import flash.events.IEventDispatcher;
import mx.collections.ArrayCollection;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.present.model.Page;
@ -51,7 +51,7 @@ package org.bigbluebutton.modules.whiteboard.models
}
public function addAnnotation(annotation:Annotation):void {
LOGGER.debug("*** Adding annotation [{0},{1},{2}] ****", [annotation.id, annotation.type, annotation.status]);
// LOGGER.debug("*** Adding annotation [{0},{1},{2}] ****", [annotation.id, annotation.type, annotation.status]);
var wb:Whiteboard;
if (annotation.status == DrawObject.DRAW_START || annotation.type == DrawObject.POLL
|| annotation.status == TextObject.TEXT_CREATED) {
@ -70,7 +70,7 @@ package org.bigbluebutton.modules.whiteboard.models
}
}
LOGGER.debug("*** Dispatching WhiteboardUpdate.BOARD_UPDATED Event ****");
// LOGGER.debug("*** Dispatching WhiteboardUpdate.BOARD_UPDATED Event ****");
var event:WhiteboardUpdate = new WhiteboardUpdate(WhiteboardUpdate.BOARD_UPDATED);
event.annotation = annotation;
_dispatcher.dispatchEvent(event);
@ -86,13 +86,13 @@ package org.bigbluebutton.modules.whiteboard.models
public function addAnnotationFromHistory(whiteboardId:String, annotation:Array):void {
LOGGER.debug("addAnnotationFromHistory: wb id=[{0}]", [whiteboardId]);
//LOGGER.debug("addAnnotationFromHistory: wb id=[{0}]", [whiteboardId]);
var wb:Whiteboard = getWhiteboard(whiteboardId);
if (wb != null) {
LOGGER.debug("Whiteboard is already present. Adding shapes.");
// LOGGER.debug("Whiteboard is already present. Adding shapes.");
addShapes(wb, annotation);
} else {
LOGGER.debug("Whiteboard is NOT present. Creating WB and adding shapes.");
// LOGGER.debug("Whiteboard is NOT present. Creating WB and adding shapes.");
wb = new Whiteboard(whiteboardId);
addShapes(wb, annotation);
_whiteboards.addItem(wb);

View File

@ -32,7 +32,7 @@ package org.bigbluebutton.util.i18n
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;
import mx.utils.URLUtil;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.events.LocaleChangeEvent;
@ -180,7 +180,10 @@ package org.bigbluebutton.util.i18n
localeIndex = getIndexForLocale(preferredLocale);
} else {
if (preferredLocale != MASTER_LOCALE) {
LOGGER.debug("Failed to load locale [{0}].", [preferredLocale]);
var logData:Object = UsersUtil.initLogData();
logData.tags = ["locale"];
logData.message = "Failed to load locale = " + preferredLocale;
LOGGER.info(JSON.stringify(logData));
}
resourceManager.localeChain = [MASTER_LOCALE];

View File

@ -120,5 +120,5 @@ find /tmp -name "*.pfb" -mtime +$history -delete
# If there are no users currently logged in, restart libreoffice to clear its memory usage
#
if [[ $(netstat -ant | egrep ":1935\ " | egrep -v ":::|0.0.0.0" | wc | awk '{print $1}') == 0 ]]; then
service libreoffice restart
systemctl restart libreoffice.service
fi

View File

@ -54,7 +54,7 @@ export default function addChat(meetingId, message) {
};
const cb = (err, numChanged) => {
if (err != null) {
if (err) {
Logger.error(`Adding chat to collection: ${err}`);
}

View File

@ -1,15 +1,3 @@
import { clearUsersCollection } from '/imports/api/users/server/modifiers/clearUsersCollection';
import clearChats from '/imports/api/chat/server/modifiers/clearChats';
import { clearShapesCollection } from '/imports/api/shapes/server/modifiers/clearShapesCollection';
import { clearSlidesCollection } from '/imports/api/slides/server/modifiers/clearSlidesCollection';
import { clearPresentationsCollection }
from '/imports/api/presentations/server/modifiers/clearPresentationsCollection';
import { clearMeetingsCollection }
from '/imports/api/meetings/server/modifiers/clearMeetingsCollection';
import { clearPollCollection } from '/imports/api/polls/server/modifiers/clearPollCollection';
import { clearCursorCollection } from '/imports/api/cursor/server/modifiers/clearCursorCollection';
import { clearCaptionsCollection }
from '/imports/api/captions/server/modifiers/clearCaptionsCollection';
import { logger } from '/imports/startup/server/logger';
import { redisPubSub } from '/imports/startup/server';
import { BREAK_LINE, CARRIAGE_RETURN, NEW_LINE } from '/imports/utils/lineEndings.js';
@ -24,42 +12,6 @@ export function appendMessageHeader(eventName, messageObj) {
return messageObj;
};
export function clearCollections() {
console.log('in function clearCollections');
/*
This is to prevent collection clearing in development environment when the server
refreshes. Related to: https://github.com/meteor/meteor/issues/6576
*/
if (process.env.NODE_ENV === 'development') {
return;
}
const meetingId = arguments[0];
if (meetingId != null) {
clearUsersCollection(meetingId);
clearChats(meetingId);
clearMeetingsCollection(meetingId);
clearShapesCollection(meetingId);
clearSlidesCollection(meetingId);
clearPresentationsCollection(meetingId);
clearPollCollection(meetingId);
clearCursorCollection(meetingId);
clearCaptionsCollection(meetingId);
} else {
clearUsersCollection();
clearChats();
clearMeetingsCollection();
clearShapesCollection();
clearSlidesCollection();
clearPresentationsCollection();
clearPollCollection();
clearCursorCollection();
clearCaptionsCollection();
}
}
export const indexOf = [].indexOf || function (item) {
for (let i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item) {

View File

@ -0,0 +1,17 @@
import RedisPubSub from '/imports/startup/server/redis';
import handleMeetingDestruction from './handlers/meetingDestruction';
import handleRecordingStatusChange from './handlers/recordingStatusChange';
import handlePermissionSettingsChange from './handlers/permissionSettingsChange';
import handleMeetingCreation from './handlers/meetingCreation';
import handleGetAllMettings from './handlers/getAllMeetings';
import handleStunTurnReply from './handlers/stunTurnReply';
RedisPubSub.on('meeting_destroyed_event', handleMeetingDestruction);
RedisPubSub.on('meeting_ended_message', handleMeetingDestruction);
RedisPubSub.on('end_and_kick_all_message', handleMeetingDestruction);
RedisPubSub.on('disconnect_all_users_message', handleMeetingDestruction);
RedisPubSub.on('recording_status_changed_message', handleRecordingStatusChange);
RedisPubSub.on('new_permission_settings', handlePermissionSettingsChange);
RedisPubSub.on('meeting_created_message', handleMeetingCreation);
RedisPubSub.on('get_all_meetings_reply_message', handleGetAllMettings);
RedisPubSub.on('send_stun_turn_info_reply_message', handleStunTurnReply);

View File

@ -0,0 +1,36 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import Meetings from '/imports/api/meetings';
import addMeeting from '../modifiers/addMeeting';
import removeMeeting from '../modifiers/removeMeeting';
export default function handleGetAllMettings({ payload }) {
let meetings = payload.meetings;
check(meetings, Array);
// We need to map the meetings payload because for some reason this payload
// is different than the `meeting_created_message` one
meetings = meetings.map(m => ({
meeting_id: m.meetingID,
name: m.meetingName,
recorded: m.recorded,
voice_conf: m.voiceBridge,
duration: m.duration,
}));
const meetingsIds = meetings.map(m => m.meeting_id);
const meetingsToRemove = Meetings.find({
meetingId: { $nin: meetingsIds },
}).fetch();
meetingsToRemove.forEach(meeting => removeMeeting(meeting.meetingId));
let meetingsAdded = [];
meetings.forEach(meeting => {
meetingsAdded.push(addMeeting(meeting));
});
return meetingsAdded;
};

View File

@ -0,0 +1,11 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import addMeeting from '../modifiers/addMeeting';
export default function handleMeetingCreation({ payload }) {
const meetingId = payload.meeting_id;
check(meetingId, String);
return addMeeting(payload);
};

View File

@ -0,0 +1,11 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import removeMeeting from '../modifiers/removeMeeting';
export default function handleMeetingDestruction({ payload }) {
const meetingId = payload.meeting_id;
check(meetingId, String);
return removeMeeting(meetingId);
};

View File

@ -0,0 +1,52 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import Meetings from '/imports/api/meetings';
import handleLockingMic from '/imports/api/users/server/modifiers/handleLockingMic';
export default function handlePermissionSettingsChange({ payload }) {
const meetingId = payload.meeting_id;
const permissions = payload.permissions;
check(meetingId, String);
check(permissions, Object);
const selector = {
meetingId,
};
const Meeting = Meetings.findOne(selector);
if (!Meeting) {
throw new Meteor.error('meeting-not-found', `Meeting id=${meetingId} was not found`);
}
const modifier = {
$set: {
roomLockSettings: {
disablePrivateChat: permissions.disablePrivateChat,
disableCam: permissions.disableCam,
disableMic: permissions.disableMic,
lockOnJoin: permissions.lockOnJoin,
lockedLayout: permissions.lockedLayout,
disablePublicChat: permissions.disablePublicChat,
lockOnJoinConfigurable: permissions.lockOnJoinConfigurable,
},
},
};
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Updating meeting permissions: ${err}`);
}
if (permissions.disableMic) {
handleLockingMic(meetingId, permissions);
}
if (numChanged) {
return Logger.info(`Updated meeting permissions id=${meetingId}`);
}
};
return Meetings.update(selector, modifier, cb);
};

View File

@ -0,0 +1,36 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import Meetings from '/imports/api/meetings';
export default function handleRecordingStatusChange({ payload }) {
const meetingId = arg.payload.meeting_id;
const intendedForRecording = arg.payload.recorded;
const currentlyBeingRecorded = arg.payload.recording;
check(meetingId, String);
check(intendedForRecording, Boolean);
check(currentlyBeingRecorded, Boolean);
const selector = {
meetingId,
intendedForRecording,
};
const modifier = {
$set: {
currentlyBeingRecorded,
},
};
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Updating meeting recording status: ${err}`);
}
if (numChanged) {
return Logger.info(`Updated meeting recording status id=${meetingId}`);
}
};
return Meetings.update(selector, modifier, cb);
};

View File

@ -0,0 +1,33 @@
import { check } from 'meteor/check';
import Logger from '/imports/startup/server/logger';
import Meetings from '/imports/api/meetings';
export default function handleStunTurnReply({ payload }) {
const meetingId = payload.meeting_id;
const { stuns, turns } = payload;
check(meetingId, String);
const selector = {
meetingId,
};
const modifier = {
$set: {
stuns,
turns,
},
};
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Updating meeting stuns/turns: ${err}`);
}
if (numChanged) {
return Logger.info(`Updated meeting stuns/turns id=${meetingId}`);
}
};
return Meetings.update(selector, modifier, cb);
};

View File

@ -0,0 +1,3 @@
import './eventHandlers';
import './methods';
import './publishers';

View File

@ -0,0 +1,4 @@
import { Meteor } from 'meteor/meteor';
Meteor.methods({
});

View File

@ -0,0 +1,55 @@
import { check } from 'meteor/check';
import Meetings from '/imports/api/meetings';
import Logger from '/imports/startup/server/logger';
import { initializeCursor } from '/imports/api/cursor/server/modifiers/initializeCursor';
export default function addMeeting(meeting) {
const APP_CONFIG = Meteor.settings.public.app;
const meetingId = meeting.meeting_id;
check(meeting, Object);
check(meetingId, String);
const selector = {
meetingId,
};
const modifier = {
$set: {
meetingId,
meetingName: meeting.name,
intendedForRecording: meeting.recorded,
currentlyBeingRecorded: false,
voiceConf: meeting.voice_conf,
duration: meeting.duration,
roomLockSettings: {
disablePrivateChat: false,
disableCam: false,
disableMic: false,
lockOnJoin: APP_CONFIG.lockOnJoin,
lockedLayout: false,
disablePublicChat: false,
lockOnJoinConfigurable: false,
},
},
};
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Adding meeting to collection: ${err}`);
}
initializeCursor(meetingId);
const { insertedId } = numChanged;
if (insertedId) {
return Logger.info(`Added meeting id=${meetingId}`);
}
if (numChanged) {
return Logger.info(`Upserted meeting id=${meetingId}`);
}
};
return Meetings.upsert(selector, modifier, cb);
};

View File

@ -1,48 +0,0 @@
import { initializeCursor } from '/imports/api/cursor/server/modifiers/initializeCursor';
import Meetings from '/imports/api/meetings';
import { logger } from '/imports/startup/server/logger';
export function addMeetingToCollection(meetingId, name, intendedForRecording,
voiceConf, duration, callback) {
const APP_CONFIG = Meteor.settings.public.app;
//check if the meeting is already in the collection
Meetings.upsert({
meetingId: meetingId,
}, {
$set: {
meetingName: name,
intendedForRecording: intendedForRecording,
currentlyBeingRecorded: false,
voiceConf: voiceConf,
duration: duration,
roomLockSettings: {
// by default the lock settings will be disabled on meeting create
disablePrivateChat: false,
disableCam: false,
disableMic: false,
lockOnJoin: APP_CONFIG.lockOnJoin,
lockedLayout: false,
disablePublicChat: false,
lockOnJoinConfigurable: false, // TODO
},
},
}, (_this => function (err, numChanged) {
let funct;
if (numChanged.insertedId != null) {
funct = function (cbk) {
logger.info(`__added MEETING ${meetingId}`);
return cbk();
};
return funct(callback);
} else {
logger.info('the meeting already existed so no information was added');
return callback();
}
}
)(this));
// initialize the cursor in the meeting
return initializeCursor(meetingId);
};

View File

@ -0,0 +1,29 @@
import Meetings from '/imports/api/chat';
import Logger from '/imports/startup/server/logger';
import removeMeeting from './removeMeeting';
import { clearUsersCollection } from '/imports/api/users/server/modifiers/clearUsersCollection';
import clearChats from '/imports/api/chat/server/modifiers/clearChats';
import { clearShapesCollection } from '/imports/api/shapes/server/modifiers/clearShapesCollection';
import { clearSlidesCollection } from '/imports/api/slides/server/modifiers/clearSlidesCollection';
import { clearPollCollection } from '/imports/api/polls/server/modifiers/clearPollCollection';
import { clearCursorCollection } from '/imports/api/cursor/server/modifiers/clearCursorCollection';
import { clearCaptionsCollection }
from '/imports/api/captions/server/modifiers/clearCaptionsCollection';
import { clearPresentationsCollection }
from '/imports/api/presentations/server/modifiers/clearPresentationsCollection';
export default function clearMeetings() {
return Meetings.remove({}, (err) => {
clearCaptionsCollection();
clearChats();
clearCursorCollection();
clearPollCollection();
clearPresentationsCollection();
clearShapesCollection();
clearSlidesCollection();
clearUsersCollection();
return Logger.info('Cleared Meetings (all)');
});
};

View File

@ -1,13 +0,0 @@
import Meetings from '/imports/api/meetings';
import { logger } from '/imports/startup/server/logger';
export function clearMeetingsCollection() {
const meetingId = arguments[0];
if (meetingId != null) {
return Meetings.remove({
meetingId: meetingId,
}, logger.info(`cleared Meetings Collection (meetingId: ${meetingId}!`));
} else {
return Meetings.remove({}, logger.info('cleared Meetings Collection (all meetings)!'));
}
};

View File

@ -1,121 +0,0 @@
import { eventEmitter } from '/imports/startup/server';
import { logger } from '/imports/startup/server/logger';
import Meetings from '/imports/api/meetings';
import { handleLockingMic } from '/imports/api/users/server/modifiers/handleLockingMic';
import { addMeetingToCollection } from './addMeetingToCollection';
import { removeMeetingFromCollection } from './removeMeetingFromCollection';
eventEmitter.on('meeting_ended_message', function (arg) {
handleEndOfMeeting(arg);
});
eventEmitter.on('send_stun_turn_info_reply_message', function (arg) {
const stuns = arg.payload.stuns;
const turns = arg.payload.turns;
const meetingId = arg.payload.meeting_id;
Meetings.update({
meetingId: meetingId,
}, {
$set: {
stuns: stuns,
turns: turns,
},
});
return arg.callback();
});
eventEmitter.on('meeting_destroyed_event', function (arg) {
handleEndOfMeeting(arg);
});
eventEmitter.on('recording_status_changed_message', function (arg) {
const intendedForRecording = arg.payload.recorded;
const currentlyBeingRecorded = arg.payload.recording;
const meetingId = arg.payload.meeting_id;
Meetings.update({
meetingId: meetingId,
intendedForRecording: intendedForRecording,
}, {
$set: {
currentlyBeingRecorded: currentlyBeingRecorded,
},
});
return arg.callback();
});
eventEmitter.on('new_permission_settings', function (arg) {
const meetingId = arg.payload.meeting_id;
const payload = arg.payload;
const meetingObject = Meetings.findOne({
meetingId: meetingId,
});
if (meetingObject != null && payload != null) {
const oldSettings = meetingObject.roomLockSettings;
const newSettings = payload.permissions;
// if the disableMic setting was turned on
if (oldSettings != null && !oldSettings.disableMic && newSettings.disableMic) {
handleLockingMic(meetingId, newSettings);
}
const settingsObj = {
disablePrivateChat: newSettings.disablePrivateChat,
disableCam: newSettings.disableCam,
disableMic: newSettings.disableMic,
lockOnJoin: newSettings.lockOnJoin,
lockedLayout: newSettings.lockedLayout,
disablePublicChat: newSettings.disablePublicChat,
lockOnJoinConfigurable: newSettings.lockOnJoinConfigurable,
};
// substitute with the new lock settings
Meetings.update({
meetingId: meetingId,
}, {
$set: {
roomLockSettings: settingsObj,
},
});
}
return arg.callback();
});
eventEmitter.on('meeting_created_message', function (arg) {
const meetingName = arg.payload.name;
const intendedForRecording = arg.payload.recorded;
const voiceConf = arg.payload.voice_conf;
const duration = arg.payload.duration;
const meetingId = arg.payload.meeting_id;
return addMeetingToCollection(meetingId, meetingName, intendedForRecording,
voiceConf, duration, arg.callback);
});
eventEmitter.on('get_all_meetings_reply_message', function (arg) {
logger.info('Let\'s store some data for the running meetings so that when an' +
' HTML5 client joins everything is ready!');
logger.info(JSON.stringify(arg.payload));
const listOfMeetings = arg.payload.meetings;
// Processing the meetings recursively with a callback to notify us,
// ensuring that we update the meeting collection serially
let processMeeting = function () {
let meeting = listOfMeetings.pop();
if (meeting != null) {
return addMeetingToCollection(meeting.meetingID, meeting.meetingName,
meeting.recorded, meeting.voiceBridge, meeting.duration, processMeeting);
} else {
return arg.callback(); // all meeting arrays (if any) have been processed
}
};
return processMeeting();
});
export const handleEndOfMeeting = function (arg) {
const meetingId = arg.payload.meeting_id;
logger.info(`DESTROYING MEETING ${meetingId}`);
return removeMeetingFromCollection(meetingId, arg.callback);
};

View File

@ -0,0 +1,43 @@
import { check } from 'meteor/check';
import Meetings from '/imports/api/meetings';
import Logger from '/imports/startup/server/logger';
import { clearUsersCollection } from '/imports/api/users/server/modifiers/clearUsersCollection';
import clearChats from '/imports/api/chat/server/modifiers/clearChats';
import { clearShapesCollection } from '/imports/api/shapes/server/modifiers/clearShapesCollection';
import { clearSlidesCollection } from '/imports/api/slides/server/modifiers/clearSlidesCollection';
import { clearPollCollection } from '/imports/api/polls/server/modifiers/clearPollCollection';
import { clearCursorCollection } from '/imports/api/cursor/server/modifiers/clearCursorCollection';
import { clearCaptionsCollection }
from '/imports/api/captions/server/modifiers/clearCaptionsCollection';
import { clearPresentationsCollection }
from '/imports/api/presentations/server/modifiers/clearPresentationsCollection';
export default function removeMeeting(meetingId) {
check(meetingId, String);
const selector = {
meetingId,
};
const cb = (err, numChanged) => {
if (err) {
return Logger.error(`Removing meeting from collection: ${err}`);
}
if (numChanged) {
clearCaptionsCollection(meetingId);
clearChats(meetingId);
clearCursorCollection(meetingId);
clearPollCollection(meetingId);
clearPresentationsCollection(meetingId);
clearShapesCollection(meetingId);
clearSlidesCollection(meetingId);
clearUsersCollection(meetingId);
return Logger.info(`Removed meeting id=${meetingId}`);
}
};
return Meetings.remove(selector, cb);
};

View File

@ -1,23 +0,0 @@
import { clearCollections } from '/imports/api/common/server/helpers';
import Meetings from '/imports/api/meetings';
import { logger } from '/imports/startup/server/logger';
//clean up upon a meeting's end
export function removeMeetingFromCollection(meetingId, callback) {
if (Meetings.findOne({
meetingId: meetingId,
}) != null) {
logger.info(`end of meeting ${meetingId}. Clear the meeting data from all collections`);
clearCollections(meetingId);
return callback();
} else {
let funct = function (localCallback) {
logger.error(`Error! There was no such meeting ${meetingId}`);
return localCallback();
};
return funct(callback);
}
};

View File

@ -1,10 +0,0 @@
import Meetings from '/imports/api/meetings';
import { logger } from '/imports/startup/server/logger';
Meteor.publish('meetings', function (credentials) {
const { meetingId } = credentials;
logger.info(`publishing meetings for ${meetingId}`);
return Meetings.find({
meetingId: meetingId,
});
});

View File

@ -0,0 +1,18 @@
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import Meetings from '/imports/api/meetings';
import Logger from '/imports/startup/server/logger';
Meteor.publish('meetings', (credentials) => {
const { meetingId, requesterUserId, requesterToken } = credentials;
check(meetingId, String);
check(requesterUserId, String);
check(requesterToken, String);
Logger.info(`Publishing meeting=${meetingId} ${requesterUserId} ${requesterToken}`);
return Meetings.find({
meetingId,
});
});

View File

@ -1,6 +1,5 @@
import { logger } from '/imports/startup/server/logger';
import { eventEmitter } from '/imports/startup/server';
import { handleEndOfMeeting } from '/imports/api/meetings/server/modifiers/eventHandlers';
import { userJoined } from './userJoined';
import { setUserLockedStatus } from './setUserLockedStatus';
import { markUserOffline } from './markUserOffline';
@ -15,14 +14,6 @@ eventEmitter.on('disconnect_user_message', function (arg) {
handleRemoveUserEvent(arg);
});
eventEmitter.on('end_and_kick_all_message', function (arg) {
handleEndOfMeeting(arg);
});
eventEmitter.on('disconnect_all_users_message', function (arg) {
handleEndOfMeeting(arg);
});
eventEmitter.on('user_left_message', function (arg) {
handleRemoveUserEvent(arg);
});

View File

@ -1,25 +1,11 @@
import { Meteor } from 'meteor/meteor';
import Locales from '/imports/locales';
import Logger from './logger';
import Redis from './redis';
import { clearCollections } from '/imports/api/common/server/helpers';
Meteor.startup(() => {
clearCollections();
const APP_CONFIG = Meteor.settings.public.app;
let determineConnectionType = function () {
let baseConnection = 'HTTP';
if (APP_CONFIG.httpsConnection) {
baseConnection += ('S');
}
return baseConnection;
};
Logger.info(`server start. Connection type:${determineConnectionType()}`);
Logger.info('APP_CONFIG=');
Logger.info(APP_CONFIG);
Logger.info('Running in environment type:' + Meteor.settings.runtime.env);
Logger.info(`SERVER STARTED. ENV=${Meteor.settings.runtime.env}`, APP_CONFIG);
});
WebApp.connectHandlers.use('/check', (req, res, next) => {

View File

@ -13,11 +13,7 @@ import '/imports/api/deskshare/server/modifiers/handleDeskShareChange';
import '/imports/api/deskshare/server/modifiers/handleIncomingDeskshareMessage';
import '/imports/api/deskshare/server/modifiers/eventHandlers';
import '/imports/api/meetings/server/publications';
import '/imports/api/meetings/server/modifiers/addMeetingToCollection';
import '/imports/api/meetings/server/modifiers/clearMeetingsCollection';
import '/imports/api/meetings/server/modifiers/removeMeetingFromCollection';
import '/imports/api/meetings/server/modifiers/eventHandlers';
import '/imports/api/meetings/server';
import '/imports/api/phone/server/modifiers/eventHandlers';

View File

@ -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 {

View File

@ -38,10 +38,10 @@
<${property}>
<#if properties[property]["image"]?? && properties[property]["image"]?is_hash>
<#assign image = properties[property]["image"]>
<image <#if image["attributes"]?? && image["attributes"]["width"]??>width="${image["attributes"]["width"]}"</#if> <#if image["attributes"]?? && image["attributes"]["height"]??>height="${image["attributes"]["height"]}"</#if> <#if image["attributes"]?? && image["attributes"]["alt"]??>alt="${image["attributes"]["alt"]}"</#if>>${image["text"]}</image>
<image <#if image["attributes"]?? && image["attributes"]["width"]??>width="${image["attributes"]["width"]}"</#if> <#if image["attributes"]?? && image["attributes"]["height"]??>height="${image["attributes"]["height"]}"</#if> <#if image["attributes"]?? && image["attributes"]["alt"]??>alt="<#escape x as x?xml>${image["attributes"]["alt"]}</#escape>"</#if>>${image["text"]}</image>
<#elseif properties[property]["image"]?is_enumerable>
<#list properties[property]["image"] as image>
<image <#if image["attributes"]?? && image["attributes"]["width"]??>width="${image["attributes"]["width"]}"</#if> <#if image["attributes"]?? && image["attributes"]["height"]??>height="${image["attributes"]["height"]}"</#if> <#if image["attributes"]?? && image["attributes"]["alt"]??>alt="${image["attributes"]["alt"]}"</#if>>${image["text"]}</image>
<image <#if image["attributes"]?? && image["attributes"]["width"]??>width="${image["attributes"]["width"]}"</#if> <#if image["attributes"]?? && image["attributes"]["height"]??>height="${image["attributes"]["height"]}"</#if> <#if image["attributes"]?? && image["attributes"]["alt"]??>alt="<#escape x as x?xml>${image["attributes"]["alt"]}</#escape>"</#if>>${image["text"]}</image>
</#list>
</#if>
</${property}>

View File

@ -2,37 +2,41 @@ GEM
remote: http://rubygems.org/
specs:
absolute_time (1.0.0)
addressable (2.3.6)
addressable (2.4.0)
builder (3.2.2)
curb (0.8.6)
fastimage (1.6.4)
addressable (~> 2.3, >= 2.3.5)
mime-types (2.4.3)
mini_portile (0.6.1)
curb (0.9.3)
fastimage (2.0.0)
addressable (~> 2)
mime-types (2.6.2)
mini_portile2 (2.1.0)
mono_logger (1.1.0)
multi_json (1.10.1)
nokogiri (1.6.4.1)
mini_portile (~> 0.6.0)
multi_json (1.12.1)
nokogiri (1.6.8)
mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
open4 (1.3.4)
rack (1.5.2)
pkg-config (1.1.7)
rack (1.6.4)
rack-protection (1.5.3)
rack
redis (3.1.0)
redis-namespace (1.5.1)
redis (3.3.1)
redis-namespace (1.5.2)
redis (~> 3.0, >= 3.0.4)
resque (1.25.2)
resque (1.26.0)
mono_logger (~> 1.0)
multi_json (~> 1.0)
redis-namespace (~> 1.3)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
rubyzip (1.1.6)
sinatra (1.4.5)
rack (~> 1.4)
rubyzip (1.2.0)
sinatra (1.4.7)
rack (~> 1.5)
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
tilt (1.4.1)
trollop (2.0)
tilt (>= 1.3, < 3)
streamio-ffmpeg (2.1.0)
multi_json (~> 1.8)
tilt (2.0.5)
trollop (2.1.2)
vegas (0.1.11)
rack (>= 1.0.0)
@ -44,13 +48,15 @@ DEPENDENCIES
builder
curb
fastimage
mime-types
mime-types (= 2.6.2)
nokogiri
open4
redis
resque
rubyzip
streamio-ffmpeg
trollop
BUNDLED WITH
1.10.6
1.12.5

View File

@ -172,15 +172,22 @@ module BigBlueButton
def self.audio_info(filename)
IO.popen([*FFPROBE, filename]) do |probe|
info = JSON.parse(probe.read, :symbolize_names => true)
if !info[:streams]
return {}
info = nil
begin
info = JSON.parse(probe.read, :symbolize_names => true)
rescue StandardError => e
BigBlueButton.logger.warn("Couldn't parse audio info: #{e}")
end
info[:audio] = info[:streams].find { |stream| stream[:codec_type] == 'audio' }
return {} if !info
return {} if !info[:streams]
return {} if !info[:format]
if info[:audio]
info[:sample_rate] = info[:audio][:sample_rate].to_i
info[:audio] = info[:streams].find do |stream|
stream[:codec_type] == 'audio'
end
return {} if !info[:audio]
info[:sample_rate] = info[:audio][:sample_rate].to_i
if info[:format][:format_name] == 'wav'
# wav files generated by freeswitch can have incorrect length

View File

@ -269,33 +269,35 @@ module BigBlueButton
def self.video_info(filename)
IO.popen([*FFPROBE, filename]) do |probe|
info = JSON.parse(probe.read, :symbolize_names => true)
info = nil
begin
info = JSON.parse(probe.read, :symbolize_names => true)
rescue StandardError => e
BigBlueButton.logger.warn("Couldn't parse video info: #{e}")
end
return {} if !info
return {} if !info[:streams]
return {} if !info[:format]
if info[:streams]
info[:video] = info[:streams].find { |stream| stream[:codec_type] == 'video' }
info[:audio] = info[:streams].find { |stream| stream[:codec_type] == 'audio' }
info[:video] = info[:streams].find do |stream|
stream[:codec_type] == 'audio'
end
if info[:video]
info[:width] = info[:video][:width].to_i
info[:height] = info[:video][:height].to_i
return {} if !info[:video]
return {} if info[:width] == 0 or info[:height] == 0
return {} if info[:video][:display_aspect_ratio] == '0:0'
info[:width] = info[:video][:width].to_i
info[:height] = info[:video][:height].to_i
info[:aspect_ratio] = info[:video][:display_aspect_ratio].to_r
if info[:aspect_ratio] == 0
info[:aspect_ratio] = Rational(info[:width], info[:height])
end
return {} if info[:width] == 0 or info[:height] == 0
return {} if info[:video][:display_aspect_ratio] == '0:0'
info[:aspect_ratio] = Rational(*(info[:video][:display_aspect_ratio].split(':')))
if info[:aspect_ratio] == 0
info[:aspect_ratio] = Rational(info[:width], info[:height])
end
# Convert the duration to milliseconds
if info[:format]
info[:duration] = (info[:format][:duration].to_r * 1000).to_i
else
info[:duration] = 0
end
info[:duration] = (info[:format][:duration].to_r * 1000).to_i
return info
end

View File

@ -99,11 +99,11 @@ module BigBlueButton
# Set textfile directory
textfiles_dir = "#{process_dir}/presentation/#{presentation_id}/textfiles"
# Set presentation hashmap to be returned
presentation[:id] = presentation_id
presentation[:filename] = presentation_filename
presentation[:slides] = {}
presentation[:slides][1] = { :alt => self.get_text_from_slide(textfiles_dir, 1) }
unless presentation_filename == "default.pdf"
presentation[:id] = presentation_id
presentation[:filename] = presentation_filename
presentation[:slides] = {}
presentation[:slides][1] = { :alt => self.get_text_from_slide(textfiles_dir, 1) } if File.file?("#{textfiles_dir}/slide-1.txt")
presentation[:slides][2] = { :alt => self.get_text_from_slide(textfiles_dir, 2) } if File.file?("#{textfiles_dir}/slide-2.txt")
presentation[:slides][3] = { :alt => self.get_text_from_slide(textfiles_dir, 3) } if File.file?("#{textfiles_dir}/slide-3.txt")
# Break because something else than default.pdf was found