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) { for (IConnection conn : conns) {
String connUserId = (String) conn.getAttribute("USERID"); String connUserId = (String) conn.getAttribute("USERID");
String connSessionId = conn.getSessionId(); 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)) { if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) {
conn.removeAttribute("USERID"); conn.removeAttribute("USERID");
Map<String, Object> logData = new HashMap<String, Object>(); Map<String, Object> logData = new HashMap<String, Object>();
@ -86,6 +89,8 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
logData.put("userId", userId); logData.put("userId", userId);
logData.put("oldConnId", connSessionId); logData.put("oldConnId", connSessionId);
logData.put("newConnId", sessionId); logData.put("newConnId", sessionId);
logData.put("clientId", clientId);
logData.put("remoteAddress", remoteHost + ":" + remotePort);
logData.put("event", "removing_defunct_connection"); logData.put("event", "removing_defunct_connection");
logData.put("description", "Removing defunct connection BBB Video."); 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>(); Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId); logData.put("meetingId", meetingId);
logData.put("userId", userId); logData.put("userId", userId);
logData.put("connType", connType); logData.put("connType", connType);
logData.put("connId", sessionId); logData.put("connId", sessionId);
logData.put("clientId", clientId);
logData.put("remoteAddress", remoteHost + ":" + remotePort);
logData.put("event", "user_joining_bbb_video"); logData.put("event", "user_joining_bbb_video");
logData.put("description", "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) { for (IConnection conn : conns) {
String connUserId = (String) conn.getAttribute("INTERNAL_USER_ID"); String connUserId = (String) conn.getAttribute("INTERNAL_USER_ID");
String connSessionId = conn.getSessionId(); 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)) { if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) {
conn.removeAttribute("INTERNAL_USER_ID"); conn.removeAttribute("INTERNAL_USER_ID");
Map<String, Object> logData = new HashMap<String, Object>(); Map<String, Object> logData = new HashMap<String, Object>();
@ -145,6 +148,8 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
logData.put("userId", userId); logData.put("userId", userId);
logData.put("oldConnId", connSessionId); logData.put("oldConnId", connSessionId);
logData.put("newConnId", sessionId); logData.put("newConnId", sessionId);
logData.put("clientId", clientId);
logData.put("remoteAddress", remoteHost + ":" + remotePort);
logData.put("event", "removing_defunct_connection"); logData.put("event", "removing_defunct_connection");
logData.put("description", "Removing defunct connection BBB Apps."); logData.put("description", "Removing defunct connection BBB Apps.");
@ -173,14 +178,15 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
String connId = Red5.getConnectionLocal().getSessionId(); String connId = Red5.getConnectionLocal().getSessionId();
String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); 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>(); Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId); logData.put("meetingId", meetingId);
logData.put("connType", connType); logData.put("connType", connType);
logData.put("connId", connId); logData.put("connId", connId);
logData.put("conn", remoteHost + ":" + remotePort); logData.put("clientId", clientId);
logData.put("remoteAddress", remoteHost + ":" + remotePort);
logData.put("userId", userId); logData.put("userId", userId);
logData.put("externalUserId", externalUserID); logData.put("externalUserId", externalUserID);
logData.put("sessionId", sessionId); logData.put("sessionId", sessionId);
@ -222,14 +228,15 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
String connType = getConnectionType(Red5.getConnectionLocal().getType()); String connType = getConnectionType(Red5.getConnectionLocal().getType());
String userFullname = bbbSession.getUsername(); String userFullname = bbbSession.getUsername();
String connId = Red5.getConnectionLocal().getSessionId(); String connId = Red5.getConnectionLocal().getSessionId();
String clientId = Red5.getConnectionLocal().getClient().getId();
String sessionId = CONN + userId; String sessionId = CONN + userId;
Map<String, Object> logData = new HashMap<String, Object>(); Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId); logData.put("meetingId", meetingId);
logData.put("connType", connType); logData.put("connType", connType);
logData.put("connId", connId); logData.put("connId", connId);
logData.put("conn", remoteHost + ":" + remotePort); logData.put("clientId", clientId);
logData.put("remoteAddress", remoteHost + ":" + remotePort);
logData.put("sessionId", sessionId); logData.put("sessionId", sessionId);
logData.put("userId", userId); logData.put("userId", userId);
logData.put("username", userFullname); logData.put("username", userFullname);

View File

@ -145,8 +145,8 @@ public class ConnectionInvokerService {
private void handlDisconnectClientMessage(DisconnectClientMessage msg) { private void handlDisconnectClientMessage(DisconnectClientMessage msg) {
IScope meetingScope = getScope(msg.getMeetingId()); IScope meetingScope = getScope(msg.getMeetingId());
if (meetingScope != null) { if (meetingScope != null) {
String sessionId = CONN + msg.getUserId(); String userId = msg.getUserId();
IConnection conn = getConnection(meetingScope, sessionId); IConnection conn = getConnection(meetingScope, userId);
if (conn != null) { if (conn != null) {
if (conn.isConnected()) { if (conn.isConnected()) {
log.info("Disconnecting user=[{}] from meeting=[{}]", msg.getUserId(), msg.getMeetingId()); 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.managers.UserManager;
import org.bigbluebutton.core.vo.CameraSettingsVO; import org.bigbluebutton.core.vo.CameraSettingsVO;
import org.bigbluebutton.main.model.users.BBBUser; import org.bigbluebutton.main.model.users.BBBUser;
import org.bigbluebutton.util.SessionTokenUtil;
public class UsersUtil public class UsersUtil
{ {
@ -194,7 +195,7 @@ package org.bigbluebutton.core
return null; return null;
} }
public static function getUserData():Object { private static function getUserData():Object {
var userData:Object = new Object(); var userData:Object = new Object();
userData.meetingId = getInternalMeetingID(); userData.meetingId = getInternalMeetingID();
userData.externalMeetingId = getExternalMeetingID(); userData.externalMeetingId = getExternalMeetingID();
@ -215,5 +216,20 @@ package org.bigbluebutton.core
return false; 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 { public function onDisconnected(type:String, callback:Function, parameters:Array):void {
if (!_canceled) { if (!_canceled) {
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.user = UsersUtil.getUserData();
logData.user.connection = type; logData.user.connection = type;
logData.tags = ["connection"];
JSLog.warn("Connection disconnected", logData);
logData.message = "Connection disconnected"; logData.message = "Connection disconnected";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
@ -110,14 +107,9 @@ package org.bigbluebutton.core.managers
} }
public function onConnectionAttemptFailed(type:String):void { public function onConnectionAttemptFailed(type:String):void {
LOGGER.warn("onConnectionAttemptFailed, type={0}", [type]); var logData:Object = UsersUtil.initLogData();
logData.user.connection = type;
var logData:Object = new Object(); logData.tags = ["connection"];
logData.user = UsersUtil.getUserData();
logData.user.connection = type;
JSLog.warn("Reconnect attempt on connection failed.", logData);
logData.message = "Reconnect attempt on connection failed."; logData.message = "Reconnect attempt on connection failed.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
@ -150,18 +142,13 @@ package org.bigbluebutton.core.managers
} }
public function onConnectionAttemptSucceeded(type:String):void { public function onConnectionAttemptSucceeded(type:String):void {
LOGGER.debug("onConnectionAttemptSucceeded, type={0}", [type]); var logData:Object = UsersUtil.initLogData();
var logData:Object = new Object();
logData.user = UsersUtil.getUserData();
logData.user.connection = type; logData.user.connection = type;
logData.tags = ["connection"];
JSLog.warn("Reconnect succeeded.", logData);
logData.message = "Reconnect succeeded."; logData.message = "Reconnect succeeded.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
dispatchReconnectionSucceededEvent(type); dispatchReconnectionSucceededEvent(type);
delete _connections[type]; delete _connections[type];
if (type == BIGBLUEBUTTON_CONNECTION) { if (type == BIGBLUEBUTTON_CONNECTION) {
reconnect(); reconnect();
@ -173,7 +160,7 @@ package org.bigbluebutton.core.managers
_dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT, _dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT,
ResourceUtil.getInstance().getString('bbb.connection.reestablished'), ResourceUtil.getInstance().getString('bbb.connection.reestablished'),
msg)); msg, 'bbb.connection.reestablished'));
_reconnectTimeout.reset(); _reconnectTimeout.reset();
removePopUp(); removePopUp();

View File

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

View File

@ -29,12 +29,14 @@ package org.bigbluebutton.main.events
public var title:String; public var title:String;
public var message:String; public var message:String;
public var logCode:String;
public function ClientStatusEvent(type:String, title:String, message:String)
public function ClientStatusEvent(type:String, title:String, message:String, logCode:String)
{ {
super(type); super(type);
this.title = title; this.title = title;
this.message = message; 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"; * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
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; } } } *
* 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.URLRequest;
import flash.net.URLRequestMethod; import flash.net.URLRequestMethod;
import flash.net.URLVariables; import flash.net.URLVariables;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger; import org.as3commons.logging.api.getClassLogger;
import org.as3commons.logging.util.jsonXify; import org.as3commons.logging.util.jsonXify;
@ -59,18 +59,29 @@ package org.bigbluebutton.main.model.modules
var result:Object = JSON.parse(e.target.data); var result:Object = JSON.parse(e.target.data);
LOGGER.debug("Enter response = {0}", [jsonXify(result)]); LOGGER.debug("Enter response = {0}", [jsonXify(result)]);
var logData:Object = UsersUtil.initLogData
var returncode:String = result.response.returncode; var returncode:String = result.response.returncode;
if (returncode == 'FAILED') { 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(); var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new MeetingNotFoundEvent(result.response.logoutURL)); dispatcher.dispatchEvent(new MeetingNotFoundEvent(result.response.logoutURL));
} else if (returncode == 'SUCCESS') { } else if (returncode == 'SUCCESS') {
LOGGER.debug("Enter API call SUCESS = {0}", [jsonXify(result)]);
var response:Object = new Object(); var response:Object = new Object();
response.username = result.response.fullname; response.username = result.response.fullname;
response.userId = result.response.internalUserID; response.userId = result.response.internalUserID;
response.meetingName = result.response.confname; response.meetingName = result.response.confname;
response.meetingId = result.response.meetingID; 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); 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.ModuleLoadEvent;
import org.bigbluebutton.main.events.PortTestEvent; import org.bigbluebutton.main.events.PortTestEvent;
import org.bigbluebutton.main.events.UserServicesEvent; import org.bigbluebutton.main.events.UserServicesEvent;
import org.bigbluebutton.main.model.ConfigParameters; import org.bigbluebutton.main.model.ConfigParameters;
public class ModulesDispatcher public class ModulesDispatcher
{ {
@ -111,31 +111,11 @@ package org.bigbluebutton.main.model.modules
dispatcher.dispatchEvent(evt); dispatcher.dispatchEvent(evt);
} }
public function sendTunnelingFailedEvent(server: String, app: String):void{ 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);
dispatcher.dispatchEvent(new PortTestEvent(PortTestEvent.TUNNELING_FAILED)); dispatcher.dispatchEvent(new PortTestEvent(PortTestEvent.TUNNELING_FAILED));
} }
public function sendPortTestSuccessEvent(port:String, host:String, tunnel:Boolean, app:String):void{ 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); var portEvent:PortTestEvent = new PortTestEvent(PortTestEvent.PORT_TEST_SUCCESS);
portEvent.port = port; 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.ILogger;
import org.as3commons.logging.api.getClassLogger; import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.main.model.ConferenceParameters; 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 { public class ModulesProxy {
private static const LOGGER:ILogger = getClassLogger(ModulesProxy); private static const LOGGER:ILogger = getClassLogger(ModulesProxy);
@ -43,7 +44,12 @@ package org.bigbluebutton.main.model.modules
} }
public function portTestSuccess(tunnel:Boolean):void { 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.useProtocol(tunnel);
modulesManager.startUserServices(); modulesManager.startUserServices();
} }

View File

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

View File

@ -26,7 +26,7 @@ package org.bigbluebutton.main.model.users
import flash.events.TimerEvent; import flash.events.TimerEvent;
import flash.net.NetConnection; import flash.net.NetConnection;
import flash.net.Responder; import flash.net.Responder;
import flash.utils.Timer; import flash.utils.Timer;
import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger; import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB; 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.ConnectionFailedEvent;
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent; import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
public class NetConnectionDelegate public class NetConnectionDelegate {
{ private static const LOGGER:ILogger = getClassLogger(NetConnectionDelegate);
private static const LOGGER:ILogger = getClassLogger(NetConnectionDelegate);
private var _netConnection:NetConnection;
private var _netConnection:NetConnection; private var connectionId:Number;
private var connectionId:Number; private var connected:Boolean = false;
private var connected:Boolean = false; private var _userid:Number = -1;
private var _role:String = "unknown";
private var _userid:Number = -1; private var logoutOnUserCommand:Boolean = false;
private var _role:String = "unknown"; private var dispatcher:Dispatcher;
private var _messageListeners:Array = new Array();
private var logoutOnUserCommand:Boolean = false; private var authenticated: Boolean = false;
private var dispatcher:Dispatcher; private var reconnecting:Boolean = false;
private var _messageListeners:Array = new Array();
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 numNetworkChangeCount:int = 0;
private var reconnecting:Boolean = false; private var _validateTokenTimer:Timer = null;
private var numNetworkChangeCount:int = 0;
private var bbbAppsUrl: String = null;
private var _validateTokenTimer:Timer = null;
public function NetConnectionDelegate():void {
dispatcher = new Dispatcher();
}
public function get connection():NetConnection {
return _netConnection;
}
public function addMessageListener(listener:IMessageListener):void { public function NetConnectionDelegate():void {
_messageListeners.push(listener); dispatcher = new Dispatcher();
} _netConnection = new NetConnection();
_netConnection.proxyType = "best";
public function removeMessageListener(listener:IMessageListener):void { _netConnection.client = this;
for (var ob:int=0; ob<_messageListeners.length; ob++) { _netConnection.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
if (_messageListeners[ob] == listener) { _netConnection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, netASyncError );
_messageListeners.splice (ob,1); _netConnection.addEventListener( SecurityErrorEvent.SECURITY_ERROR, netSecurityError );
break; _netConnection.addEventListener( IOErrorEvent.IO_ERROR, netIOError );
} }
}
}
private function notifyListeners(messageName:String, message:Object):void { public function get connection():NetConnection {
if (messageName != null && messageName != "") { return _netConnection;
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 );
try { public function addMessageListener(listener:IMessageListener):void {
var appURL:String = BBB.getConfigManager().config.application.uri; _messageListeners.push(listener);
var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/; }
var result:Array = pattern.exec(appURL);
public function removeMessageListener(listener:IMessageListener):void {
var protocol:String = "rtmp"; for (var ob:int=0; ob<_messageListeners.length; ob++) {
var uri:String = appURL + "/" + confParams.room; if (_messageListeners[ob] == listener) {
_messageListeners.splice (ob,1);
if (BBB.initConnectionManager().isTunnelling) { break;
uri = "rtmpt://" + result.server + "/" + result.app + "/" + confParams.room; }
} else { }
uri = "rtmp://" + result.server + ":1935/" + result.app + "/" + confParams.room; }
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(); private function validataTokenTimerHandler(event:TimerEvent):void {
logData.user = UsersUtil.getUserData(); 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) { var map:Object = JSON.parse(msg.msg);
case "NetConnection.Connect.Success": var tokenValid: Boolean = map.valid as Boolean;
numNetworkChangeCount = 0; var userId: String = map.userId as String;
JSLog.debug("Successfully connected to BBB App.", logData);
validateToken(); var logData:Object = UsersUtil.initLogData();
break; logData.tags = ["apps", "connected"];
logData.tokenValid = tokenValid;
case "NetConnection.Connect.Failed": logData.key = "validate_token_response_received";
LOGGER.error(":Connection to viewers application failed...even when tunneling"); logData.message = "Validate auth token timed out.";
sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_FAILED); LOGGER.info(JSON.stringify(logData));
break;
if (tokenValid) {
case "NetConnection.Connect.Closed": authenticated = true;
logData.message = "NetConnection.Connect.Closed on bbb-apps"; } else {
LOGGER.info(JSON.stringify(logData)); dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_CLOSED); }
break;
if (reconnecting) {
case "NetConnection.Connect.InvalidApp": onReconnect();
LOGGER.debug(":viewers application not found on server"); reconnecting = false;
sendConnectionFailedEvent(ConnectionFailedEvent.INVALID_APP); }
break; }
case "NetConnection.Connect.AppShutDown": private function handleValidateAuthTokenReply(msg: Object):void {
LOGGER.debug(":viewers application has been shutdown"); stopValidateTokenTimer();
sendConnectionFailedEvent(ConnectionFailedEvent.APP_SHUTDOWN);
break; var map:Object = JSON.parse(msg.msg);
var tokenValid: Boolean = map.valid as Boolean;
case "NetConnection.Connect.Rejected": var userId: String = map.userId as String;
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]); var logData:Object = UsersUtil.initLogData();
sendConnectionFailedEvent(ConnectionFailedEvent.CONNECTION_REJECTED); logData.tags = ["apps", "connected"];
break; logData.tokenValid = tokenValid;
logData.status = "validate_token_response_received";
case "NetConnection.Connect.NetworkChange": logData.message = "Received validate token response from server.";
numNetworkChangeCount++; LOGGER.info(JSON.stringify(logData));
if (numNetworkChangeCount % 20 == 0) {
logData.message = "Detected network change on bbb-apps"; if (tokenValid) {
logData.numNetworkChangeCount = numNetworkChangeCount; authenticated = true;
LOGGER.info(JSON.stringify(logData)); } else {
} dispatcher.dispatchEvent(new InvalidAuthTokenEvent());
break; }
default : if (reconnecting) {
LOGGER.debug(":Default status to the viewers application" ); onReconnect();
sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); reconnecting = false;
break; }
} }
}
private function onReconnect():void {
protected function netSecurityError(event: SecurityErrorEvent):void { if (authenticated) {
LOGGER.error("Security error - {0}", [event.text]); onReconnectSuccess();
sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); } else {
} onReconnectFailed();
}
protected function netIOError(event: IOErrorEvent):void { }
LOGGER.error("Input/output error - {0}", [event.text]);
sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON); private function onReconnectSuccess():void {
} var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT);
attemptSucceeded.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
protected function netASyncError(event: AsyncErrorEvent):void { dispatcher.dispatchEvent(attemptSucceeded);
LOGGER.debug("Asynchronous code error - {0}", [event.toString()]); }
sendConnectionFailedEvent(ConnectionFailedEvent.UNKNOWN_REASON);
} 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{ private function sendConnectionFailedEvent(reason:String):void{
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.tags = ["apps", "connection"];
if (this.logoutOnUserCommand) { if (this.logoutOnUserCommand) {
logData.reason = "User requested."; logData.reason = "User requested.";
logData.user = UsersUtil.getUserData();
logData.message = "User logged out from BBB App."; logData.message = "User logged out from BBB App.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
sendUserLoggedOutEvent(); sendUserLoggedOutEvent();
} else if (reason == ConnectionFailedEvent.CONNECTION_CLOSED && !UsersUtil.isUserEjected()) { } else if (reason == ConnectionFailedEvent.CONNECTION_CLOSED && !UsersUtil.isUserEjected()) {
// do not try to reconnect if the connection failed is different than CONNECTION_CLOSED // do not try to reconnect if the connection failed is different than CONNECTION_CLOSED
logData.reason = reason; logData.reason = reason;
logData.user = UsersUtil.getUserData();
logData.message = "User disconnected from BBB App."; logData.message = "User disconnected from BBB App.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
if (reconnecting) { if (reconnecting) {
var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT); var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
attemptFailedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; attemptFailedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
dispatcher.dispatchEvent(attemptFailedEvent); dispatcher.dispatchEvent(attemptFailedEvent);
} else { } else {
reconnecting = true; reconnecting = true;
authenticated = false; authenticated = false;
var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT); var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT);
disconnectedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION; disconnectedEvent.payload.type = ReconnectionManager.BIGBLUEBUTTON_CONNECTION;
disconnectedEvent.payload.callback = connect; disconnectedEvent.payload.callback = connect;
disconnectedEvent.payload.callbackParameters = new Array(); disconnectedEvent.payload.callbackParameters = new Array();
dispatcher.dispatchEvent(disconnectedEvent); dispatcher.dispatchEvent(disconnectedEvent);
} }
} else { } else {
if (UsersUtil.isUserEjected()) { if (UsersUtil.isUserEjected()) {
logData.user = UsersUtil.getUserData();
logData.message = "User has been ejected from meeting."; logData.message = "User has been ejected from meeting.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
reason = ConnectionFailedEvent.USER_EJECTED_FROM_MEETING; 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{ private function sendUserLoggedOutEvent():void{
var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT); var e:ConnectionFailedEvent = new ConnectionFailedEvent(ConnectionFailedEvent.USER_LOGGED_OUT);
dispatcher.dispatchEvent(e); dispatcher.dispatchEvent(e);
} }
public function onBWCheck(... rest):Number { public function onBWCheck(... rest):Number {
return 0; return 0;
} }
public function onBWDone(... rest):void { public function onBWDone(... rest):void {
var p_bw:Number; var p_bw:Number;
if (rest.length > 0) p_bw = rest[0]; if (rest.length > 0) p_bw = rest[0];
// your application should do something here // your application should do something here
// when the bandwidth check is complete // when the bandwidth check is complete
LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]); LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]);
} }
} }
} }

View File

@ -18,23 +18,22 @@
*/ */
package org.bigbluebutton.main.model.users.events package org.bigbluebutton.main.model.users.events
{ {
import flash.events.Event; import flash.events.Event;
public class ConnectionFailedEvent extends Event public class ConnectionFailedEvent extends Event {
{ public static const UNKNOWN_REASON:String = "unknownReason";
public static const UNKNOWN_REASON:String = "unknownReason"; public static const CONNECTION_FAILED:String = "connectionFailed";
public static const CONNECTION_FAILED:String = "connectionFailed"; public static const CONNECTION_CLOSED:String = "connectionClosed";
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 INVALID_APP:String = "invalidApp";
public static const APP_SHUTDOWN:String = "appShutdown"; public static const APP_SHUTDOWN:String = "appShutdown";
public static const CONNECTION_REJECTED:String = "connectionRejected"; public static const CONNECTION_REJECTED:String = "connectionRejected";
public static const ASYNC_ERROR:String = "asyncError"; public static const ASYNC_ERROR:String = "asyncError";
public static const USER_LOGGED_OUT:String = "userHasLoggedOut"; public static const USER_LOGGED_OUT:String = "userHasLoggedOut";
public static const USER_EJECTED_FROM_MEETING:String = "userHasBeenEjectFromMeeting"; public static const USER_EJECTED_FROM_MEETING:String = "userHasBeenEjectFromMeeting";
public function ConnectionFailedEvent(type:String) public function ConnectionFailedEvent(type:String) {
{ super(type, true, false);
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 com.asfusion.mate.events.Dispatcher;
import flash.ui.Keyboard; import flash.ui.Keyboard;
import org.bigbluebutton.core.UsersUtil;
import mx.controls.sliderClasses.Slider; import mx.controls.sliderClasses.Slider;
import mx.events.CloseEvent; import mx.events.CloseEvent;
import mx.events.SliderEvent; import mx.events.SliderEvent;
@ -100,7 +100,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function reInitialize():void { private function reInitialize():void {
my_nc = new NetConnection(); my_nc = new NetConnection();
my_nc.proxyType = "best"; my_nc.proxyType = "best";
my_nc.connect(null); my_nc.connect(null);
nsStream = new NetStream(my_nc); nsStream = new NetStream(my_nc);
if (mic != null) { if (mic != null) {
@ -127,14 +127,21 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
audioMicLevelDetected = 0; audioMicLevelDetected = 0;
} }
private function micStatusEventHandler(event:StatusEvent):void { private function micStatusEventHandler(event:StatusEvent):void {
var logData:Object = UsersUtil.initLogData();
switch(event.code) { switch(event.code) {
case "Microphone.Muted": case "Microphone.Muted":
LOGGER.debug("Access to microphone has been denied."); 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."; statusText.text = "You did not allow Flash to access your mic.";
break; break;
case "Microphone.Unmuted": 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 // Comment these next 2-lines. We don't want the user hearing audio
// while testing mic levels. (richard mar 26, 2014) // while testing mic levels. (richard mar 26, 2014)
// mic.setLoopBack(true); // mic.setLoopBack(true);
@ -155,7 +162,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
micActivityTimer.start(); micActivityTimer.start();
} }
private function onCreationComplete():void { private function onCreationComplete():void {
LOGGER.debug("onCreationComplete. Seeting state to [flashMicSettingsTest]"); LOGGER.debug("onCreationComplete. Seeting state to [flashMicSettingsTest]");
microphoneList = Media.getMicrophoneNames(); microphoneList = Media.getMicrophoneNames();
setupForMicLoopbackTest(); setupForMicLoopbackTest();
@ -252,7 +259,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
} }
private function onCancelClicked():void { private function onCancelClicked():void {
LOGGER.debug("onCancelClicked closing popup");
cleanUp(); cleanUp();
stopEchoTest(); stopEchoTest();
var dispatcher:Dispatcher = new Dispatcher(); var dispatcher:Dispatcher = new Dispatcher();
@ -292,7 +298,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
} }
private function yesButtonClicked():void { 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(); cleanUp();
dispatchEvent(new FlashEchoTestHasAudioEvent()); dispatchEvent(new FlashEchoTestHasAudioEvent());
var dispatcher:Dispatcher = new Dispatcher(); var dispatcher:Dispatcher = new Dispatcher();
@ -301,7 +311,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
} }
private function noButtonClicked():void { 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()); dispatchEvent(new FlashEchoTestNoAudioEvent());
testMicrophoneLoopback(); testMicrophoneLoopback();
setupForMicLoopbackTest(); 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 Foundation; either version 3.0 of the License, or (at your option) any later
version. version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY 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 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 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.users.views.BreakoutRoomSettings;
import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent; import org.bigbluebutton.modules.videoconf.events.ShareCameraRequestEvent;
import org.bigbluebutton.util.i18n.ResourceUtil; import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.core.UsersUtil;
private static const LOGGER:ILogger = getClassLogger(MainApplicationShell); 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 { private function handleApplicationVersionEvent(event:AppVersionEvent):void {
var logData:Object = UsersUtil.initLogData();
if (event.configLocaleVersion == true) { if (event.configLocaleVersion == true) {
receivedConfigLocaleVer = true; receivedConfigLocaleVer = true;
appVersion = event.appVersion; appVersion = event.appVersion;
localeVersion = event.localeVersion; 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"); LOGGER.debug("Received locale version fron config.xml");
} else { } else {
receivedResourceLocaleVer = true; 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) { if (receivedConfigLocaleVer && receivedResourceLocaleVer) {
@ -252,11 +265,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function fullScreenHandler(evt:FullScreenEvent):void { private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")"; dispState = stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) { if (evt.fullScreen) {
LOGGER.debug("Switching to full screen");
/* Do something specific here if we switched to full screen mode. */ /* Do something specific here if we switched to full screen mode. */
} else { } else {
LOGGER.debug("Switching to normal screen");
/* Do something specific here if we switched to normal mode. */ /* 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{ private function toggleFullScreen():void{
LOGGER.debug("Toggling fullscreen");
try { try {
switch (stage.displayState) { switch (stage.displayState) {
case StageDisplayState.FULL_SCREEN: case StageDisplayState.FULL_SCREEN:
LOGGER.debug("full screen mode");
// If already in full screen mode, switch to normal mode. // If already in full screen mode, switch to normal mode.
stage.displayState = StageDisplayState.NORMAL; stage.displayState = StageDisplayState.NORMAL;
break; break;
default: default:
LOGGER.debug("Normal screen mode");
// If not in full screen mode, switch to full screen mode. // If not in full screen mode, switch to full screen mode.
stage.displayState = StageDisplayState.FULL_SCREEN; stage.displayState = StageDisplayState.FULL_SCREEN;
break; 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 // this is a terrible place for these checks because this function runs 4 times on startup
if (BBB.initConnectionManager().isTunnelling) { if (BBB.initConnectionManager().isTunnelling) {
isTunneling = true; 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(); 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) { 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, globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.browser.title"), 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 //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)) { ((flashVersion.os != 'LNX' || browserVersion[0].toString().toLowerCase() == "chrome") && flashVersion.major < xml.@flash)) {
globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT, globalDispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.flash.title"), 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"; Alert.okLabel ="OK";
var version:String = "old-locales"; var version:String = "old-locales";
version = ResourceUtil.getInstance().getString('bbb.mainshell.locale.version'); 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)) { if ((version == "old-locales") || (version == "") || (version == null)) {
wrongLocaleVersion(); wrongLocaleVersion();
} else { } else {
@ -630,7 +650,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
} }
private function onFooterLinkClicked(e:TextEvent):void{ private function onFooterLinkClicked(e:TextEvent):void{
LOGGER.debug("Clicked on link[{0}] from footer", [e.text]);
if (ExternalInterface.available) { if (ExternalInterface.available) {
ExternalInterface.call("chatLinkClicked", e.text); 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 { private function logFlashPlayerCapabilities():void {
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.user = UsersUtil.getUserData(); logData.tags = ["initialization"];
logData.capabilities = getFlashPlayerCapabilities(); logData.capabilities = getFlashPlayerCapabilities();
logData.message = "Flash Player Capabilities."; logData.message = "Flash Player Capabilities.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));

View File

@ -94,7 +94,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
messages.push(obj); messages.push(obj);
showNotification(); 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 { private function showNotification():void {
@ -102,7 +108,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
visible = includeInLayout = true; visible = includeInLayout = true;
if (hideTimer.running) hideTimer.reset(); if (hideTimer.running) hideTimer.reset();
hideTimer.start() hideTimer.start();
if (!notification) { if (!notification) {
notification = ToolTipManager.createToolTip(ResourceUtil.getInstance().getString("bbb.clientstatus.notification"), 100, 100, "errorTipAbove", this) as ToolTip; 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; userClosed = true;
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.reason = "User requested."; logData.reason = "User requested.";
logData.user = UsersUtil.getUserData(); logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test passed."; logData.message = "WebRtc Echo test passed.";
JSLog.info("WebRtc Echo test passed.", logData);
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
setCurrentState("connecting"); setCurrentState("connecting");
@ -120,11 +117,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
private function noButtonClicked():void { private function noButtonClicked():void {
userClosed = true; userClosed = true;
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.reason = "User requested."; logData.reason = "User requested.";
logData.user = UsersUtil.getUserData(); logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test failed."; logData.message = "WebRtc Echo test failed.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));
var dispatcher:Dispatcher = new Dispatcher(); var dispatcher:Dispatcher = new Dispatcher();
@ -190,9 +186,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
} }
private function webRTCCallStarted():void { private function webRTCCallStarted():void {
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.reason = "User requested."; logData.reason = "User requested.";
logData.user = UsersUtil.getUserData(); logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc call started."; logData.message = "WebRtc call started.";
LOGGER.info(JSON.stringify(logData)); LOGGER.info(JSON.stringify(logData));

View File

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

View File

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

View File

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

View File

@ -14,7 +14,6 @@ package org.bigbluebutton.modules.phone.managers
import org.as3commons.logging.util.jsonXify; import org.as3commons.logging.util.jsonXify;
import org.bigbluebutton.core.UsersUtil; import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.api.JSAPI; import org.bigbluebutton.main.api.JSAPI;
import org.bigbluebutton.main.api.JSLog;
import org.bigbluebutton.main.events.ClientStatusEvent; import org.bigbluebutton.main.events.ClientStatusEvent;
import org.bigbluebutton.main.model.users.AutoReconnect; import org.bigbluebutton.main.model.users.AutoReconnect;
import org.bigbluebutton.modules.phone.PhoneModel; import org.bigbluebutton.modules.phone.PhoneModel;
@ -32,7 +31,7 @@ package org.bigbluebutton.modules.phone.managers
public class WebRTCCallManager public class WebRTCCallManager
{ {
private static const LOGGER:ILogger = getClassLogger(WebRTCCallManager); private static const LOGGER:ILogger = getClassLogger(WebRTCCallManager);
private const MAX_RETRIES:Number = 3; private const MAX_RETRIES:Number = 3;
private var browserType:String = "unknown"; private var browserType:String = "unknown";
@ -60,7 +59,8 @@ package org.bigbluebutton.modules.phone.managers
if (options.useWebRTCIfAvailable && !isWebRTCSupported()) { if (options.useWebRTCIfAvailable && !isWebRTCSupported()) {
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT, dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.clientstatus.webrtc.title"), 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(); usingWebRTC = checkIfToUseWebRTC();
@ -135,7 +135,8 @@ package org.bigbluebutton.modules.phone.managers
if(reconnecting) { if(reconnecting) {
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.SUCCESS_MESSAGE_EVENT, 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"))); ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.reestablished"),
'bbb.webrtcWarning.connection.reestablished'));
reconnecting = false; reconnecting = false;
} }
} }
@ -150,8 +151,12 @@ package org.bigbluebutton.modules.phone.managers
} }
public function handleJoinVoiceConferenceCommand(event:JoinVoiceConferenceCommand):void { 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 (!usingWebRTC || !event.mic) return;
if (options.skipCheck || echoTestDone) { if (options.skipCheck || echoTestDone) {
@ -200,28 +205,34 @@ package org.bigbluebutton.modules.phone.managers
errorString = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.unknown", [event.errorCode]); errorString = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.unknown", [event.errorCode]);
} }
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.user = UsersUtil.getUserData(); logData.user.reason = errorString;
logData.user.reason = errorString; logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test failed."; logData.message = "WebRtc Echo test failed.";
JSLog.warn("WebRtc Echo test failed.", logData); logData.errorEvent = event;
LOGGER.info(jsonXify(logData));
LOGGER.info(jsonXify(logData));
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"),
sendWebRTCAlert(ResourceUtil.getInstance().getString("bbb.webrtcWarning.title"), ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]), errorString); ResourceUtil.getInstance().getString("bbb.webrtcWarning.message", [errorString]),
errorString,
'bbb.webrtcWarning webRTCEchoTestFailedEvent');
} }
public function handleWebRTCEchoTestEndedUnexpectedly():void { public function handleWebRTCEchoTestEndedUnexpectedly():void {
model.state = Constants.INITED; model.state = Constants.INITED;
var errorString:String = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.endedunexpectedly"); var logCode:String = "bbb.webrtcWarning.failedError.endedunexpectedly";
var errorString:String = ResourceUtil.getInstance().getString(logCode);
var logData:Object = new Object();
logData.user = UsersUtil.getUserData(); var logData:Object = UsersUtil.initLogData();
logData.user.reason = errorString; logData.user.reason = errorString;
logData.tags = ["voice", "webrtc"];
logData.message = "WebRtc Echo test ended unexpectedly."; logData.message = "WebRtc Echo test ended unexpectedly.";
LOGGER.info(jsonXify(logData)); 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,
logCode);
} }
public function handleWebRTCCallFailedEvent(event:WebRTCCallEvent):void { public function handleWebRTCCallFailedEvent(event:WebRTCCallEvent):void {
@ -233,7 +244,8 @@ package org.bigbluebutton.modules.phone.managers
reconnecting = true; reconnecting = true;
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT, dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.WARNING_MESSAGE_EVENT,
ResourceUtil.getInstance().getString("bbb.webrtcWarning.connection.dropped"), 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, []); reconnect.onDisconnect(joinVoiceConference, []);
} }
else { else {
@ -256,26 +268,32 @@ package org.bigbluebutton.modules.phone.managers
errorString = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.unknown", [event.errorCode]); errorString = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.unknown", [event.errorCode]);
} }
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.user = UsersUtil.getUserData(); logData.tags = ["voice", "webrtc"];
logData.user.reason = errorString; logData.errorEvent = event;
LOGGER.info(jsonXify(logData)); 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 { public function handleWebRTCMediaFailedEvent():void {
model.state = Constants.INITED; model.state = Constants.INITED;
var errorString:String = ResourceUtil.getInstance().getString("bbb.webrtcWarning.failedError.mediamissing"); var logCode:String = "bbb.webrtcWarning.failedError.mediamissing";
var errorString:String = ResourceUtil.getInstance().getString(logCode);
var logData:Object = new Object();
logData.user = UsersUtil.getUserData(); var logData:Object = UsersUtil.initLogData();
logData.user.reason = errorString; logData.user.reason = errorString;
LOGGER.info(jsonXify(logData)); 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,
logCode);
} }
private var popUpDelayTimer:Timer = new Timer(100, 1); 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 * 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 * 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); Alert.show(message, title, Alert.YES | Alert.NO, null, handleCallFailedUserResponse, null, Alert.YES);
}); });
popUpDelayTimer.start(); 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.URLRequest;
import flash.net.URLRequestMethod; import flash.net.URLRequestMethod;
import flash.net.URLVariables; import flash.net.URLVariables;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger; import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.present.events.UploadCompletedEvent; import org.bigbluebutton.modules.present.events.UploadCompletedEvent;
import org.bigbluebutton.modules.present.events.UploadIoErrorEvent; import org.bigbluebutton.modules.present.events.UploadIoErrorEvent;
import org.bigbluebutton.modules.present.events.UploadProgressEvent; 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 class FileUploadService {
public static const ID:String = "FileUploadService"; public static const ID:String = "FileUploadService";
@ -125,8 +125,12 @@ package org.bigbluebutton.modules.present.business
* *
*/ */
private function onUploadIoError(event:IOErrorEvent):void { private function onUploadIoError(event:IOErrorEvent):void {
if(event.errorID != 2038){ //upload works despite of this error. if (event.errorID != 2038){ //upload works despite of this error.
LOGGER.error("onUploadIoError text: {0}, errorID: {1}", [event.text, event.errorID]); var logData:Object = UsersUtil.initLogData();
logData.tags = ["presentation"];
logData.message = "IOError while uploading presentation.";
LOGGER.error(JSON.stringify(logData));
dispatcher.dispatchEvent(new UploadIoErrorEvent()); dispatcher.dispatchEvent(new UploadIoErrorEvent());
} }
@ -138,8 +142,11 @@ package org.bigbluebutton.modules.present.business
* *
*/ */
private function onUploadSecurityError(event:SecurityErrorEvent) : void { private function onUploadSecurityError(event:SecurityErrorEvent) : void {
dispatcher.dispatchEvent(new UploadSecurityErrorEvent()); var logData:Object = UsersUtil.initLogData();
LOGGER.error("A security error occured while trying to upload the presentation. {0}", [event.toString()]); 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[ <![CDATA[
import mx.collections.ArrayCollection; import mx.collections.ArrayCollection;
import mx.utils.StringUtil; import mx.utils.StringUtil;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger; import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Images; import org.bigbluebutton.common.Images;
@ -158,12 +158,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
if (fileSize > maxFileSizeBytes) { if (fileSize > maxFileSizeBytes) {
// Hardcode for now to 30M limit. // Hardcode for now to 30M limit.
// This should be configurable to match what's allowed in nginx. (ralam feb 23, 2010) // 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(); enableControls();
displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert')); displayAlert(ResourceUtil.getInstance().getString('bbb.presentation.maxUploadFileExceededAlert'));
} else { } else {
var presentationName:String = StringUtil.trim(fileToUpload.name); var presentationName:String = StringUtil.trim(fileToUpload.name);
LOGGER.debug("Uploading file : {0}", [presentationName]);
progBarLbl.visible = true; progBarLbl.visible = true;
lblFileName.enabled = false; 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.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager; import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent; import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.screenshare.events.WebRTCViewStreamEvent; import org.bigbluebutton.modules.screenshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.screenshare.services.red5.WebRTCConnectionEvent; import org.bigbluebutton.modules.screenshare.services.red5.WebRTCConnectionEvent;
public class WebRTCConnection { public class WebRTCConnection {
private static const LOGGER:ILogger = getClassLogger(Connection); private static const LOGGER:ILogger = getClassLogger(Connection);
@ -168,6 +168,12 @@ package org.bigbluebutton.modules.screenshare.services.red5
private function netStatusHandler(event:NetStatusEvent):void { private function netStatusHandler(event:NetStatusEvent):void {
LOGGER.debug("Connected to [" + getURI() + "]. [" + event.info.code + "]"); 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) { if (retryTimer) {
retryCount = 0; retryCount = 0;
LOGGER.debug("Cancelling retry timer."); LOGGER.debug("Cancelling retry timer.");
@ -211,7 +217,7 @@ package org.bigbluebutton.modules.screenshare.services.red5
LOGGER.debug(result); LOGGER.debug(result);
}, },
function(status:String):void { // status - On error occurred 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; break;
case "NetConnection.Connect.NetworkChange": 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; break;
default : default :

View File

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

View File

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

View File

@ -23,7 +23,7 @@ package org.bigbluebutton.modules.users.services
import org.bigbluebutton.core.BBB; import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.UsersUtil; import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ConnectionManager; import org.bigbluebutton.core.managers.ConnectionManager;
import org.bigbluebutton.main.api.JSLog; import org.bigbluebutton.main.api.JSLog;
public class MessageSender { public class MessageSender {
private static const LOGGER:ILogger = getClassLogger(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(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); );
@ -50,7 +54,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); );
}
}
public function emojiStatus(userID:String, emoji:String):void {
var message:Object = new Object(); public function emojiStatus(userID:String, emoji:String):void {
message["emojiStatus"] = emoji; var message:Object = new Object();
message["userId"] = userID; message["emojiStatus"] = emoji;
var _nc:ConnectionManager = BBB.initConnectionManager(); message["userId"] = userID;
_nc.sendMessage("participants.userEmojiStatus", function(result:String):void
{ // On successful result var _nc:ConnectionManager = BBB.initConnectionManager();
}, function(status:String):void _nc.sendMessage("participants.userEmojiStatus",
{ // status - On error occurred function(result:String):void { // On successful result
LOGGER.error(status);
}, }, function(status:String):void { // status - On error occurred
message 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 { public function createBreakoutRooms(meetingId:String, rooms:Array, durationInMinutes:int, record:Boolean, redirectOnJoin:Boolean):void {
var message:Object = new Object(); var message:Object = new Object();
@ -102,7 +117,10 @@ package org.bigbluebutton.modules.users.services
// On successful result // On successful result
}, function(status:String):void }, function(status:String):void
{ // status - On error occurred { // 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 jsonMsg
); );
@ -121,7 +139,10 @@ package org.bigbluebutton.modules.users.services
_nc.sendMessage("breakoutroom.requestBreakoutJoinUrl", function(result:String):void { _nc.sendMessage("breakoutroom.requestBreakoutJoinUrl", function(result:String):void {
// On successful result // On successful result
}, function(status:String):void { // status - On error occurred }, 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); }, jsonMsg);
} }
@ -132,7 +153,10 @@ package org.bigbluebutton.modules.users.services
// On successful result // On successful result
}, function(status:String):void }, function(status:String):void
{ // status - On error occurred { // 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}) JSON.stringify({meetingId: meetingId, targetMeetingId: targetMeetingId, userId: userId})
); );
@ -145,7 +169,10 @@ package org.bigbluebutton.modules.users.services
// On successful result // On successful result
}, function(status:String):void }, function(status:String):void
{ // status - On error occurred { // 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}) JSON.stringify({meetingId: meetingId})
); );
@ -157,29 +184,33 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 streamName
); );
} }
public function removeStream(userID:String, streamName:String):void { public function removeStream(userID:String, streamName:String):void {
var logData:Object = new Object(); var logData:Object = UsersUtil.initLogData();
logData.user = UsersUtil.getUserData(); logData.tags = ["webcam"];
logData.streamId = streamName;
JSLog.warn("User stopped sharing webcam event.", logData); logData.message = "User stopped sharing webcam";
LOGGER.info(JSON.stringify(logData));
logData.streamId = streamName;
logData.message = "User stopped sharing webcam";
LOGGER.info(JSON.stringify(logData));
var _nc:ConnectionManager = BBB.initConnectionManager(); var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("participants.unshareWebcam", _nc.sendMessage("participants.unshareWebcam",
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 streamName
); );
@ -192,7 +223,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 ); //_netConnection.call
} }
@ -208,7 +242,10 @@ package org.bigbluebutton.modules.users.services
// On successful result // On successful result
}, function(status:String):void }, function(status:String):void
{ // status - On error occurred { // 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 jsonMsg
); );
@ -225,7 +262,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); //_netConnection.call ); //_netConnection.call
@ -241,7 +281,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); );
@ -257,7 +300,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); );
@ -274,7 +320,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); );
@ -290,7 +339,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); );
@ -305,7 +357,10 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 message
); );
@ -421,10 +482,13 @@ package org.bigbluebutton.modules.users.services
function(result:String):void { // On successful result function(result:String):void { // On successful result
}, },
function(status:String):void { // status - On error occurred 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 newLockSettings
); );
} }
} }
} }

View File

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

View File

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

View File

@ -32,7 +32,7 @@ package org.bigbluebutton.util.i18n
import mx.resources.IResourceManager; import mx.resources.IResourceManager;
import mx.resources.ResourceManager; import mx.resources.ResourceManager;
import mx.utils.URLUtil; import mx.utils.URLUtil;
import org.bigbluebutton.core.UsersUtil;
import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger; import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.events.LocaleChangeEvent; import org.bigbluebutton.common.events.LocaleChangeEvent;
@ -180,7 +180,10 @@ package org.bigbluebutton.util.i18n
localeIndex = getIndexForLocale(preferredLocale); localeIndex = getIndexForLocale(preferredLocale);
} else { } else {
if (preferredLocale != MASTER_LOCALE) { 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]; 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 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 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 fi

View File

@ -54,7 +54,7 @@ export default function addChat(meetingId, message) {
}; };
const cb = (err, numChanged) => { const cb = (err, numChanged) => {
if (err != null) { if (err) {
Logger.error(`Adding chat to collection: ${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 { logger } from '/imports/startup/server/logger';
import { redisPubSub } from '/imports/startup/server'; import { redisPubSub } from '/imports/startup/server';
import { BREAK_LINE, CARRIAGE_RETURN, NEW_LINE } from '/imports/utils/lineEndings.js'; import { BREAK_LINE, CARRIAGE_RETURN, NEW_LINE } from '/imports/utils/lineEndings.js';
@ -24,42 +12,6 @@ export function appendMessageHeader(eventName, messageObj) {
return 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) { export const indexOf = [].indexOf || function (item) {
for (let i = 0, l = this.length; i < l; i++) { for (let i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item) { 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 { logger } from '/imports/startup/server/logger';
import { eventEmitter } from '/imports/startup/server'; import { eventEmitter } from '/imports/startup/server';
import { handleEndOfMeeting } from '/imports/api/meetings/server/modifiers/eventHandlers';
import { userJoined } from './userJoined'; import { userJoined } from './userJoined';
import { setUserLockedStatus } from './setUserLockedStatus'; import { setUserLockedStatus } from './setUserLockedStatus';
import { markUserOffline } from './markUserOffline'; import { markUserOffline } from './markUserOffline';
@ -15,14 +14,6 @@ eventEmitter.on('disconnect_user_message', function (arg) {
handleRemoveUserEvent(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) { eventEmitter.on('user_left_message', function (arg) {
handleRemoveUserEvent(arg); handleRemoveUserEvent(arg);
}); });

View File

@ -1,25 +1,11 @@
import { Meteor } from 'meteor/meteor';
import Locales from '/imports/locales'; import Locales from '/imports/locales';
import Logger from './logger'; import Logger from './logger';
import Redis from './redis'; import Redis from './redis';
import { clearCollections } from '/imports/api/common/server/helpers';
Meteor.startup(() => { Meteor.startup(() => {
clearCollections();
const APP_CONFIG = Meteor.settings.public.app; const APP_CONFIG = Meteor.settings.public.app;
Logger.info(`SERVER STARTED. ENV=${Meteor.settings.runtime.env}`, APP_CONFIG);
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);
}); });
WebApp.connectHandlers.use('/check', (req, res, next) => { 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/handleIncomingDeskshareMessage';
import '/imports/api/deskshare/server/modifiers/eventHandlers'; import '/imports/api/deskshare/server/modifiers/eventHandlers';
import '/imports/api/meetings/server/publications'; import '/imports/api/meetings/server';
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/phone/server/modifiers/eventHandlers'; import '/imports/api/phone/server/modifiers/eventHandlers';

View File

@ -18,6 +18,8 @@
*/ */
package org.bigbluebutton.web.controllers package org.bigbluebutton.web.controllers
import com.google.gson.Gson
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import java.net.URI; import java.net.URI;
@ -1455,7 +1457,7 @@ class ApiController {
reject = true reject = true
} else { } else {
sessionToken = StringUtils.strip(params.sessionToken) sessionToken = StringUtils.strip(params.sessionToken)
log.info("SessionToken = " + sessionToken) log.info("Getting ConfigXml for SessionToken = " + sessionToken)
if (!session[sessionToken]) { if (!session[sessionToken]) {
reject = true reject = true
} else { } else {
@ -1478,6 +1480,20 @@ class ApiController {
} }
} }
} else { } 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") response.addHeader("Cache-Control", "no-cache")
render text: us.configXML, contentType: 'text/xml' render text: us.configXML, contentType: 'text/xml'
} }
@ -1544,7 +1560,20 @@ class ApiController {
// how many times a user reconnects or refresh the browser. // how many times a user reconnects or refresh the browser.
String newInternalUserID = us.internalUserId + "_" + us.incrementConnectionNum() 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") response.addHeader("Cache-Control", "no-cache")
withFormat { withFormat {
json { json {

View File

@ -38,10 +38,10 @@
<${property}> <${property}>
<#if properties[property]["image"]?? && properties[property]["image"]?is_hash> <#if properties[property]["image"]?? && properties[property]["image"]?is_hash>
<#assign image = properties[property]["image"]> <#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> <#elseif properties[property]["image"]?is_enumerable>
<#list properties[property]["image"] as image> <#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> </#list>
</#if> </#if>
</${property}> </${property}>

View File

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

View File

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

View File

@ -269,33 +269,35 @@ module BigBlueButton
def self.video_info(filename) def self.video_info(filename)
IO.popen([*FFPROBE, filename]) do |probe| 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
return {} if !info[:streams]
return {} if !info[:format]
if info[:streams] info[:video] = info[:streams].find do |stream|
info[:video] = info[:streams].find { |stream| stream[:codec_type] == 'video' } stream[:codec_type] == 'audio'
info[:audio] = info[:streams].find { |stream| stream[:codec_type] == 'audio' }
end end
if info[:video] return {} if !info[:video]
info[:width] = info[:video][:width].to_i
info[:height] = info[:video][:height].to_i
return {} if info[:width] == 0 or info[:height] == 0 info[:width] = info[:video][:width].to_i
return {} if info[:video][:display_aspect_ratio] == '0:0' info[:height] = info[:video][:height].to_i
info[:aspect_ratio] = info[:video][:display_aspect_ratio].to_r return {} if info[:width] == 0 or info[:height] == 0
if info[:aspect_ratio] == 0 return {} if info[:video][:display_aspect_ratio] == '0:0'
info[:aspect_ratio] = Rational(info[:width], info[:height])
end info[:aspect_ratio] = Rational(*(info[:video][:display_aspect_ratio].split(':')))
if info[:aspect_ratio] == 0
info[:aspect_ratio] = Rational(info[:width], info[:height])
end end
# Convert the duration to milliseconds # Convert the duration to milliseconds
if info[:format] info[:duration] = (info[:format][:duration].to_r * 1000).to_i
info[:duration] = (info[:format][:duration].to_r * 1000).to_i
else
info[:duration] = 0
end
return info return info
end end

View File

@ -99,11 +99,11 @@ module BigBlueButton
# Set textfile directory # Set textfile directory
textfiles_dir = "#{process_dir}/presentation/#{presentation_id}/textfiles" textfiles_dir = "#{process_dir}/presentation/#{presentation_id}/textfiles"
# Set presentation hashmap to be returned # 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" 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][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") 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 # Break because something else than default.pdf was found