Merge branch 'master' of git://github.com/bigbluebutton/bigbluebutton
This commit is contained in:
commit
1c2908911f
@ -21,6 +21,12 @@ package org.bigbluebutton.common
|
||||
[Bindable]
|
||||
public class Images
|
||||
{
|
||||
[Embed(source="assets/images/bandwidth.png")]
|
||||
public var bandwidth:Class;
|
||||
|
||||
[Embed(source="assets/images/statistics.png")]
|
||||
public var stats:Class;
|
||||
|
||||
[Embed(source="assets/images/avatar.png")]
|
||||
public var avatar:Class;
|
||||
|
||||
|
BIN
bigbluebutton-client/src/org/bigbluebutton/common/assets/images/bandwidth.png
Executable file
BIN
bigbluebutton-client/src/org/bigbluebutton/common/assets/images/bandwidth.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 880 B |
BIN
bigbluebutton-client/src/org/bigbluebutton/common/assets/images/statistics.png
Executable file
BIN
bigbluebutton-client/src/org/bigbluebutton/common/assets/images/statistics.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 403 B |
@ -2,7 +2,6 @@ package org.bigbluebutton.core
|
||||
{
|
||||
import org.bigbluebutton.core.managers.ConfigManager2;
|
||||
import org.bigbluebutton.core.managers.ConnectionManager;
|
||||
import org.bigbluebutton.core.managers.StreamManager;
|
||||
import org.bigbluebutton.core.managers.UserConfigManager;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.core.model.Session;
|
||||
@ -10,7 +9,6 @@ package org.bigbluebutton.core
|
||||
|
||||
public class BBB {
|
||||
private static var configManager:ConfigManager2 = null;
|
||||
private static var streamManager:StreamManager = null;
|
||||
private static var connectionManager:ConnectionManager = null;
|
||||
private static var session:Session = null;
|
||||
private static var userConfigManager:UserConfigManager = null;
|
||||
@ -34,13 +32,6 @@ package org.bigbluebutton.core
|
||||
return initConfigManager().config.getConfigFor(module);
|
||||
}
|
||||
|
||||
public static function initStreamManager():StreamManager {
|
||||
if (streamManager == null) {
|
||||
streamManager = new StreamManager();
|
||||
}
|
||||
return streamManager;
|
||||
}
|
||||
|
||||
public static function initConnectionManager():ConnectionManager {
|
||||
if (connectionManager == null) {
|
||||
connectionManager = new ConnectionManager();
|
||||
|
@ -1,10 +0,0 @@
|
||||
package org.bigbluebutton.core.managers
|
||||
{
|
||||
public class StreamManager
|
||||
{
|
||||
public function StreamManager()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
145
bigbluebutton-client/src/org/bigbluebutton/core/services/BandwidthMonitor.as
Executable file
145
bigbluebutton-client/src/org/bigbluebutton/core/services/BandwidthMonitor.as
Executable file
@ -0,0 +1,145 @@
|
||||
package org.bigbluebutton.core.services
|
||||
{
|
||||
import flash.events.AsyncErrorEvent;
|
||||
import flash.events.NetStatusEvent;
|
||||
import flash.events.TimerEvent;
|
||||
import flash.net.NetConnection;
|
||||
import flash.utils.Timer;
|
||||
|
||||
import mx.utils.ObjectUtil;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.main.model.NetworkStatsData;
|
||||
|
||||
import org.red5.flash.bwcheck.ClientServerBandwidth;
|
||||
import org.red5.flash.bwcheck.ServerClientBandwidth;
|
||||
import org.red5.flash.bwcheck.events.BandwidthDetectEvent;
|
||||
|
||||
public class BandwidthMonitor {
|
||||
private var _serverURL:String = "localhost";
|
||||
private var _serverApplication:String = "video";
|
||||
private var _clientServerService:String = "checkBandwidthUp";
|
||||
private var _serverClientService:String = "checkBandwidth";
|
||||
private var nc:NetConnection;
|
||||
|
||||
private var bwTestTimer:Timer;
|
||||
|
||||
public function BandwidthMonitor() {
|
||||
|
||||
}
|
||||
|
||||
public function set serverURL(url:String):void {
|
||||
_serverURL = url;
|
||||
}
|
||||
|
||||
public function set serverApplication(app:String):void {
|
||||
_serverApplication = app;
|
||||
}
|
||||
|
||||
public function start():void {
|
||||
connect();
|
||||
}
|
||||
|
||||
private function connect():void {
|
||||
nc = new NetConnection();
|
||||
nc.objectEncoding = flash.net.ObjectEncoding.AMF0;
|
||||
nc.client = this;
|
||||
nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
|
||||
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
|
||||
nc.connect("rtmp://" + _serverURL + "/" + _serverApplication);
|
||||
}
|
||||
|
||||
private function onAsyncError(event:AsyncErrorEvent):void
|
||||
{
|
||||
LogUtil.debug(event.error.toString());
|
||||
}
|
||||
|
||||
private function onStatus(event:NetStatusEvent):void
|
||||
{
|
||||
switch (event.info.code)
|
||||
{
|
||||
case "NetConnection.Connect.Success":
|
||||
LogUtil.debug("Starting to monitor bandwidth between client and server");
|
||||
monitor();
|
||||
break;
|
||||
default:
|
||||
LogUtil.debug("Cannot establish the connection to measure bandwidth");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function monitor():void {
|
||||
LogUtil.debug("Starting to monitor bandwidth");
|
||||
bwTestTimer = new Timer(30000);
|
||||
bwTestTimer.addEventListener(TimerEvent.TIMER, rtmptRetryTimerHandler);
|
||||
bwTestTimer.start();
|
||||
}
|
||||
|
||||
private function rtmptRetryTimerHandler(event:TimerEvent):void {
|
||||
LogUtil.debug("Starting to detect bandwidth from server to client");
|
||||
ServerClient();
|
||||
}
|
||||
|
||||
public function ClientServer():void
|
||||
{
|
||||
var clientServer:ClientServerBandwidth = new ClientServerBandwidth();
|
||||
//connect();
|
||||
clientServer.connection = nc;
|
||||
clientServer.service = _clientServerService;
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_COMPLETE,onClientServerComplete);
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_STATUS,onClientServerStatus);
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_FAILED,onDetectFailed);
|
||||
clientServer.start();
|
||||
}
|
||||
|
||||
public function ServerClient():void
|
||||
{
|
||||
var serverClient:ServerClientBandwidth = new ServerClientBandwidth();
|
||||
//connect();
|
||||
serverClient.connection = nc;
|
||||
serverClient.service = _serverClientService;
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_COMPLETE,onServerClientComplete);
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_STATUS,onServerClientStatus);
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_FAILED,onDetectFailed);
|
||||
serverClient.start();
|
||||
}
|
||||
|
||||
public function onDetectFailed(event:BandwidthDetectEvent):void
|
||||
{
|
||||
LogUtil.debug("Detection failed with error: " + event.info.application + " " + event.info.description);
|
||||
}
|
||||
|
||||
public function onClientServerComplete(event:BandwidthDetectEvent):void
|
||||
{
|
||||
// LogUtil.debug("Client-slient bandwidth detect complete");
|
||||
|
||||
// LogUtil.debug(ObjectUtil.toString(event.info));
|
||||
NetworkStatsData.getInstance().setUploadMeasuredBW(event.info);
|
||||
}
|
||||
|
||||
public function onClientServerStatus(event:BandwidthDetectEvent):void
|
||||
{
|
||||
if (event.info) {
|
||||
// LogUtil.debug("\n count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" overhead: "+event.info.overhead+" packet interval: " + event.info.pakInterval + " cumLatency: " + event.info.cumLatency);
|
||||
}
|
||||
}
|
||||
|
||||
public function onServerClientComplete(event:BandwidthDetectEvent):void
|
||||
{
|
||||
// LogUtil.debug("Server-client bandwidth detect complete");
|
||||
|
||||
// LogUtil.debug(ObjectUtil.toString(event.info));
|
||||
NetworkStatsData.getInstance().setDownloadMeasuredBW(event.info);
|
||||
|
||||
// LogUtil.debug("Detecting Client Server Bandwidth");
|
||||
ClientServer();
|
||||
}
|
||||
|
||||
public function onServerClientStatus(event:BandwidthDetectEvent):void
|
||||
{
|
||||
if (event.info) {
|
||||
// LogUtil.debug("\n count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" cumLatency: " + event.info.cumLatency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
212
bigbluebutton-client/src/org/bigbluebutton/core/services/StreamMonitor.as
Executable file
212
bigbluebutton-client/src/org/bigbluebutton/core/services/StreamMonitor.as
Executable file
@ -0,0 +1,212 @@
|
||||
package org.bigbluebutton.core.services
|
||||
{
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flash.events.NetDataEvent;
|
||||
import flash.events.NetMonitorEvent;
|
||||
import flash.events.NetStatusEvent;
|
||||
import flash.events.StatusEvent;
|
||||
import flash.events.TimerEvent;
|
||||
import flash.net.NetMonitor;
|
||||
import flash.net.NetStream;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.Timer;
|
||||
import flash.utils.getDefinitionByName;
|
||||
import flash.utils.getQualifiedClassName;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.main.events.NetworkStatsEvent;
|
||||
import org.bigbluebutton.main.model.NetworkStatsData;
|
||||
|
||||
public class StreamMonitor
|
||||
{
|
||||
/**
|
||||
* https://github.com/ritzalam/red5-bw-check
|
||||
* http://help.adobe.com/en_US/as3/dev/WS901d38e593cd1bac-1201e73713000d1f624-8000.html
|
||||
* http://www.adobe.com/devnet/video/articles/media-measurement-flash.html
|
||||
* http://help.adobe.com/en_US/air/reference/html/flash/net/NetMonitor.html
|
||||
* http://help.adobe.com/en_US/flashmediaserver/devguide/WSae44d1d92c7021ff-1f5381712889cd7b56-8000.html#WSae44d1d92c7021ff-1f5381712889cd7b56-7ff7
|
||||
* http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStreamInfo.html
|
||||
* http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html
|
||||
* http://help.adobe.com/en_US/FlashMediaServer/3.5_Deving/WS5b3ccc516d4fbf351e63e3d11a0773d56e-7ffa.html
|
||||
* https://groups.google.com/d/topic/red5interest/PiUDeH6jZBQ/discussion
|
||||
* http://flowplayer.electroteque.org/bwcheck
|
||||
* http://code.google.com/p/flowplayer-plugins/
|
||||
* http://osflash.org/pipermail/red5_osflash.org/2009-January/028906.html
|
||||
*/
|
||||
|
||||
private var _netmon:NetMonitor;
|
||||
private var _heartbeat:Timer = new Timer( 2000 );
|
||||
private var _globalDispatcher:Dispatcher = new Dispatcher();
|
||||
private var _totalBytesCounter:Dictionary = new Dictionary();
|
||||
|
||||
public function StreamMonitor():void {
|
||||
//Create NetMonitor object
|
||||
_netmon = new NetMonitor();
|
||||
_netmon.addEventListener( NetMonitorEvent.NET_STREAM_CREATE, newNetStream );
|
||||
|
||||
//Start the heartbeat timer
|
||||
_heartbeat.addEventListener( TimerEvent.TIMER, onHeartbeat );
|
||||
_heartbeat.start();
|
||||
}
|
||||
|
||||
//On new NetStream
|
||||
private function newNetStream(event:NetMonitorEvent):void
|
||||
{
|
||||
log("New Netstream object: " + event);
|
||||
var stream:NetStream = event.netStream;
|
||||
log("Stream info: " + stream.info);
|
||||
stream.addEventListener(NetDataEvent.MEDIA_TYPE_DATA, onStreamData);
|
||||
stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
|
||||
stream.addEventListener(StatusEvent.STATUS, onStatus);
|
||||
}
|
||||
|
||||
//On data events from a NetStream object
|
||||
private function onStreamData(event:NetDataEvent):void {
|
||||
var netStream:NetStream = event.target as NetStream;
|
||||
// log("Data event from " + netStream.info.uri + " at " + event.timestamp);
|
||||
log("Data event: " + event);
|
||||
switch(event.info.handler) {
|
||||
case "onMetaData":
|
||||
//handle metadata;
|
||||
break;
|
||||
case "onXMPData":
|
||||
//handle XMP;
|
||||
break;
|
||||
case "onPlayStatus":
|
||||
//handle NetStream.Play.Complete
|
||||
break;
|
||||
case "onImageData":
|
||||
//handle image
|
||||
break;
|
||||
case "onTextData":
|
||||
//handle text
|
||||
break;
|
||||
default:
|
||||
//handle other events
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//On status events from a NetStream object
|
||||
private function onNetStatus(event:NetStatusEvent):void {
|
||||
// log("Status event from " + event.target.info.uri + " at " + event.target.time);
|
||||
log("NetStatus event code: " + event.info.code);
|
||||
log("NetStatus event details: " + event.info.details);
|
||||
log("Stream info: " + event.target.info);
|
||||
}
|
||||
|
||||
private function onStatus(event:StatusEvent):void {
|
||||
log("Status event code: " + event.code);
|
||||
log("Status event: " + event.target);
|
||||
log("Stream info: " + event.currentTarget);
|
||||
}
|
||||
|
||||
private function isRemoteStream(stream:NetStream):Boolean {
|
||||
return (stream != null && stream.info != null && stream.info.resourceName != null);
|
||||
}
|
||||
|
||||
//On heartbeat timer
|
||||
private function onHeartbeat(event:TimerEvent):void {
|
||||
var streams:Vector.<NetStream> = _netmon.listStreams();
|
||||
|
||||
var download:Dictionary = new Dictionary();
|
||||
var upload:Dictionary = new Dictionary();
|
||||
|
||||
for (var i:int = 0; i < streams.length; i++) {
|
||||
if (streams[i] == null || streams[i].info == null) {
|
||||
// stream info is null, returning
|
||||
continue;
|
||||
}
|
||||
|
||||
// log("Heartbeat on " + streams[i].info);
|
||||
|
||||
var remote:Boolean = isRemoteStream(streams[i]);
|
||||
var ref:Dictionary = (remote? download: upload);
|
||||
|
||||
if (streams[i].info.uri == null) {
|
||||
log("Stream URI is null, returning");
|
||||
continue;
|
||||
}
|
||||
var uri:String = streams[i].info.uri.toLowerCase();
|
||||
var pattern1:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)\/(?P<meeting>.+)/;
|
||||
var pattern2:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
|
||||
var result:Array;
|
||||
var protocol:String = "", server:String = "", app:String = "", meeting:String = "";
|
||||
if (uri.match(pattern1)) {
|
||||
result = pattern1.exec(uri);
|
||||
protocol = result.protocol;
|
||||
server = result.server;
|
||||
app = result.app;
|
||||
meeting = result.meeting;
|
||||
} else if (uri.match(pattern2)) {
|
||||
result = pattern2.exec(uri);
|
||||
protocol = result.protocol;
|
||||
server = result.server;
|
||||
app = result.app;
|
||||
} else {
|
||||
log("***** NO MATCH *****");
|
||||
}
|
||||
|
||||
var props:XMLList = flash.utils.describeType(streams[i].info)..accessor;
|
||||
|
||||
for each (var s:XML in props) {
|
||||
//log(s + ": " + streams[i].info[s]);
|
||||
if (s.@type == "Number") {
|
||||
var property:String = s.@name;
|
||||
var num:Number = 0;
|
||||
if (ref.hasOwnProperty(property))
|
||||
num = ref[property] as Number;
|
||||
num += (streams[i].info[property] as Number);
|
||||
ref[property] = num;
|
||||
}
|
||||
}
|
||||
var streamName:String = app + "/" + (remote? streams[i].info.resourceName: "local");
|
||||
var streamsName:String = (ref.hasOwnProperty("streams")? ref["streams"] + ";":"") + streamName;
|
||||
ref["streams"] = streamsName;
|
||||
|
||||
var totalReg:Object = new Object;
|
||||
totalReg.streamName = streamName;
|
||||
totalReg.remote = remote;
|
||||
totalReg.byteCount = streams[i].info["byteCount"];
|
||||
if (_totalBytesCounter.hasOwnProperty(streamName) && _totalBytesCounter[streamName].byteCount > totalReg.byteCount) {
|
||||
var curTime:Number = new Date().getTime();
|
||||
var newStreamName:String = streamName + "_" + curTime;
|
||||
_totalBytesCounter[streamName].streamName = newStreamName;
|
||||
_totalBytesCounter[newStreamName] = _totalBytesCounter[streamName];
|
||||
delete _totalBytesCounter[streamName];
|
||||
}
|
||||
_totalBytesCounter[streamName] = totalReg;
|
||||
}
|
||||
|
||||
download["byteCount"] = upload["byteCount"] = 0;
|
||||
for each (var value:Object in _totalBytesCounter) {
|
||||
if (value.remote)
|
||||
download["byteCount"] += value.byteCount;
|
||||
else
|
||||
upload["byteCount"] += value.byteCount;
|
||||
//log(value.streamName + ": " + value.byteCount);
|
||||
}
|
||||
|
||||
// var netstatsEvent:NetworkStatsEvent = new NetworkStatsEvent();
|
||||
// netstatsEvent.downloadStats = download;
|
||||
// netstatsEvent.uploadStats = upload;
|
||||
// _globalDispatcher.dispatchEvent(netstatsEvent);
|
||||
|
||||
NetworkStatsData.getInstance().updateConsumedBW(download["currentBytesPerSecond"],
|
||||
upload["currentBytesPerSecond"],
|
||||
download["byteCount"],
|
||||
upload["byteCount"]);
|
||||
}
|
||||
|
||||
static public function printDictionary(dict:Dictionary):void {
|
||||
for (var key:Object in dict) {
|
||||
LogUtil.debug(key + ": " + dict[key]);
|
||||
}
|
||||
}
|
||||
|
||||
private function log(s:String):void {
|
||||
LogUtil.debug("[StreamMonitor] " + s);
|
||||
}
|
||||
}
|
||||
}
|
19
bigbluebutton-client/src/org/bigbluebutton/main/events/NetworkStatsEvent.as
Executable file
19
bigbluebutton-client/src/org/bigbluebutton/main/events/NetworkStatsEvent.as
Executable file
@ -0,0 +1,19 @@
|
||||
package org.bigbluebutton.main.events
|
||||
{
|
||||
import flash.events.Event;
|
||||
import flash.utils.Dictionary;
|
||||
|
||||
public class NetworkStatsEvent extends Event
|
||||
{
|
||||
public static const NETWORK_STATS_EVENTS:String = "NETWORK_STATS_EVENTS";
|
||||
|
||||
public var downloadStats:Dictionary;
|
||||
public var uploadStats:Dictionary;
|
||||
|
||||
public function NetworkStatsEvent(bubbles:Boolean=true, cancelable:Boolean=false)
|
||||
{
|
||||
super(NETWORK_STATS_EVENTS, bubbles, cancelable);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@
|
||||
<ObjectBuilder generator="{ModulesProxy}" cache="global" />
|
||||
<ObjectBuilder generator="{UserService}" cache="global" />
|
||||
<ObjectBuilder generator="{ConfigManager}" cache="global" />
|
||||
<ObjectBuilder generator="{StreamMonitor}" cache="global" />
|
||||
</EventHandlers>
|
||||
|
||||
<EventHandlers type="{PortTestEvent.TEST_RTMP}" >
|
||||
@ -104,13 +105,14 @@
|
||||
<EventHandlers type="{ModuleLoadEvent.LAYOUT_MODULE_STARTED}">
|
||||
<MethodInvoker generator="{ModulesProxy}" method="startAllModules" />
|
||||
</EventHandlers>
|
||||
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import mx.events.FlexEvent;
|
||||
|
||||
import org.bigbluebutton.core.managers.ConfigManager;
|
||||
import org.bigbluebutton.core.services.SkinningService;
|
||||
import org.bigbluebutton.core.services.StreamMonitor;
|
||||
import org.bigbluebutton.main.events.ConfigEvent;
|
||||
import org.bigbluebutton.main.events.LogoutEvent;
|
||||
import org.bigbluebutton.main.events.ModuleLoadEvent;
|
||||
|
@ -0,0 +1,113 @@
|
||||
package org.bigbluebutton.main.model
|
||||
{
|
||||
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.main.events.NetworkStatsEvent;
|
||||
|
||||
import flash.events.EventDispatcher;
|
||||
|
||||
public class NetworkStatsData extends EventDispatcher
|
||||
{
|
||||
private static var _instance:NetworkStatsData = null;
|
||||
private var _currentConsumedDownBW:Number = 0; // Kb
|
||||
private var _currentConsumedUpBW:Number = 0; // Kb
|
||||
private var _totalConsumedDownBW:Number = 0; // MB
|
||||
private var _totalConsumedUpBW:Number = 0; // MB
|
||||
private var _measuredDownBW:int = 0; // Mb
|
||||
private var _measuredDownLatency:int = 0; // ms
|
||||
private var _measuredUpBW:int = 0; // Mb
|
||||
private var _measuredUpLatency:int = 0; // ms
|
||||
|
||||
/**
|
||||
* This class is a singleton. Please initialize it using the getInstance() method.
|
||||
*/
|
||||
public function NetworkStatsData(enforcer:SingletonEnforcer) {
|
||||
if (enforcer == null) {
|
||||
throw new Error("There can only be one instance of this class");
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
private function initialize():void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the single instance of this class
|
||||
*/
|
||||
public static function getInstance():NetworkStatsData {
|
||||
if (_instance == null){
|
||||
_instance = new NetworkStatsData(new SingletonEnforcer());
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
// all the numbers are in bytes
|
||||
public function updateConsumedBW(down:Number, up:Number, downTotal:Number, upTotal:Number):void {
|
||||
_currentConsumedDownBW = (down * 8)/1024;
|
||||
_currentConsumedUpBW = (up * 8)/1024;
|
||||
_totalConsumedDownBW = downTotal / 1048576;
|
||||
_totalConsumedUpBW = upTotal / 1048576;
|
||||
}
|
||||
|
||||
/*
|
||||
12/8/2012 17:24:38.293 [DEBUG] (Array)#0
|
||||
[deltaDown] 2455.704
|
||||
[deltaTime] 170
|
||||
[kbitDown] 14445
|
||||
[latency] 10
|
||||
*/
|
||||
public function setDownloadMeasuredBW(info:Object):void {
|
||||
_measuredDownBW = info["kbitDown"] / 1000;
|
||||
_measuredDownLatency = info["latency"];
|
||||
}
|
||||
|
||||
/*
|
||||
12/8/2012 17:24:39.556 [DEBUG] (Object)#0
|
||||
deltaTime = 1
|
||||
deltaUp = 10516
|
||||
kbitUp = 10516
|
||||
KBytes = 1283
|
||||
latency = 11
|
||||
*/
|
||||
public function setUploadMeasuredBW(info:Object):void {
|
||||
_measuredUpBW = info.kbitUp / 1000;
|
||||
_measuredUpLatency = info.latency;
|
||||
}
|
||||
|
||||
public function get currentConsumedDownBW():Number {
|
||||
return _currentConsumedDownBW;
|
||||
}
|
||||
|
||||
public function get currentConsumedUpBW():Number {
|
||||
return _currentConsumedUpBW;
|
||||
}
|
||||
|
||||
public function get totalConsumedDownBW():Number {
|
||||
return _totalConsumedDownBW;
|
||||
}
|
||||
|
||||
public function get totalConsumedUpBW():Number {
|
||||
return _totalConsumedUpBW;
|
||||
}
|
||||
|
||||
public function get measuredDownBW():int {
|
||||
return _measuredDownBW;
|
||||
}
|
||||
|
||||
public function get measuredDownLatency():int {
|
||||
return _measuredDownLatency;
|
||||
}
|
||||
|
||||
public function get measuredUpBW():int {
|
||||
return _measuredUpBW;
|
||||
}
|
||||
|
||||
public function get measuredUpLatency():int {
|
||||
return _measuredUpLatency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SingletonEnforcer{}
|
@ -18,16 +18,13 @@
|
||||
*/
|
||||
package org.bigbluebutton.main.model.users
|
||||
{
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
import flash.events.*;
|
||||
import flash.net.NetConnection;
|
||||
import flash.net.Responder;
|
||||
import flash.utils.Timer;
|
||||
|
||||
import mx.controls.Alert;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.services.BandwidthMonitor;
|
||||
import org.bigbluebutton.main.model.ConferenceParameters;
|
||||
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
|
||||
import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
|
||||
@ -68,51 +65,45 @@ package org.bigbluebutton.main.model.users
|
||||
_netConnection.addEventListener( IOErrorEvent.IO_ERROR, netIOError );
|
||||
}
|
||||
|
||||
public function setUri(uri:String):void {
|
||||
_applicationURI = uri;
|
||||
}
|
||||
public function setUri(uri:String):void {
|
||||
_applicationURI = uri;
|
||||
}
|
||||
|
||||
|
||||
public function get connection():NetConnection {
|
||||
return _netConnection;
|
||||
}
|
||||
|
||||
public function addMessageListener(listener:IMessageListener):void
|
||||
{
|
||||
_messageListeners.push(listener);
|
||||
}
|
||||
public function addMessageListener(listener:IMessageListener):void {
|
||||
_messageListeners.push(listener);
|
||||
}
|
||||
|
||||
public function removeMessageListener(listener:IMessageListener):void
|
||||
{
|
||||
for (var ob:int=0; ob<_messageListeners.length; ob++)
|
||||
{
|
||||
if (_messageListeners[ob]==listener)
|
||||
{
|
||||
_messageListeners.splice (ob,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function removeMessageListener(listener:IMessageListener):void {
|
||||
for (var ob:int=0; ob<_messageListeners.length; ob++) {
|
||||
if (_messageListeners[ob] == listener) {
|
||||
_messageListeners.splice (ob,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function notifyListeners(messageName:String, message:Object):void
|
||||
{
|
||||
if (messageName != null && messageName != "") {
|
||||
for (var notify:String in _messageListeners)
|
||||
{
|
||||
_messageListeners[notify].onMessage(messageName, message);
|
||||
}
|
||||
} else {
|
||||
LogUtil.debug("Message name is undefined");
|
||||
}
|
||||
}
|
||||
private function notifyListeners(messageName:String, message:Object):void {
|
||||
if (messageName != null && messageName != "") {
|
||||
for (var notify:String in _messageListeners) {
|
||||
_messageListeners[notify].onMessage(messageName, message);
|
||||
}
|
||||
} else {
|
||||
LogUtil.debug("Message name is undefined");
|
||||
}
|
||||
}
|
||||
|
||||
public function onMessageFromServer(messageName:String, result:Object):void {
|
||||
// LogUtil.debug("Got message from server [" + messageName + "]");
|
||||
notifyListeners(messageName, result);
|
||||
}
|
||||
public function onMessageFromServer(messageName:String, result:Object):void {
|
||||
trace("Got message from server [" + messageName + "]");
|
||||
notifyListeners(messageName, result);
|
||||
}
|
||||
|
||||
public function sendMessage(service:String, onSuccess:Function, onFailure:Function, message:Object=null):void {
|
||||
// LogUtil.debug("SENDING [" + service + "]");
|
||||
trace("SENDING [" + service + "]");
|
||||
var responder:Responder = new Responder(
|
||||
function(result:Object):void { // On successful result
|
||||
onSuccess("Successfully sent [" + service + "].");
|
||||
@ -130,7 +121,6 @@ package org.bigbluebutton.main.model.users
|
||||
} else {
|
||||
_netConnection.call(service, responder, message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,8 +132,7 @@ package org.bigbluebutton.main.model.users
|
||||
* 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(params:ConferenceParameters, tunnel:Boolean = false):void
|
||||
{
|
||||
public function connect(params:ConferenceParameters, tunnel:Boolean = false):void {
|
||||
_conferenceParameters = params;
|
||||
|
||||
tried_tunneling = tunnel;
|
||||
@ -157,10 +146,9 @@ package org.bigbluebutton.main.model.users
|
||||
_conferenceParameters.room, _conferenceParameters.voicebridge,
|
||||
_conferenceParameters.record, _conferenceParameters.externUserID,
|
||||
_conferenceParameters.internalUserID);
|
||||
} catch( e : ArgumentError ) {
|
||||
} catch(e:ArgumentError) {
|
||||
// Invalid parameters.
|
||||
switch ( e.errorID )
|
||||
{
|
||||
switch (e.errorID) {
|
||||
case 2004 :
|
||||
LogUtil.debug("Error! Invalid server location: " + uri);
|
||||
break;
|
||||
@ -171,8 +159,7 @@ package org.bigbluebutton.main.model.users
|
||||
}
|
||||
}
|
||||
|
||||
public function disconnect(logoutOnUserCommand:Boolean) : void
|
||||
{
|
||||
public function disconnect(logoutOnUserCommand:Boolean):void {
|
||||
this.logoutOnUserCommand = logoutOnUserCommand;
|
||||
_netConnection.close();
|
||||
}
|
||||
@ -182,22 +169,33 @@ package org.bigbluebutton.main.model.users
|
||||
_netConnection.close();
|
||||
}
|
||||
|
||||
protected function netStatus( event : NetStatusEvent ) : void
|
||||
{
|
||||
protected function netStatus(event:NetStatusEvent):void {
|
||||
handleResult( event );
|
||||
}
|
||||
|
||||
private var _bwMon:BandwidthMonitor = new BandwidthMonitor();
|
||||
|
||||
private function startMonitoringBandwidth():void {
|
||||
trace("Start monitoring bandwidth.");
|
||||
var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
|
||||
var result:Array = pattern.exec(_applicationURI);
|
||||
_bwMon.serverURL = result.server;
|
||||
_bwMon.serverApplication = "video";
|
||||
_bwMon.start();
|
||||
}
|
||||
|
||||
private var autoReconnectTimer:Timer = new Timer(1000, 1);
|
||||
|
||||
public function handleResult( event : Object ) : void {
|
||||
public function handleResult(event:Object):void {
|
||||
var info : Object = event.info;
|
||||
var statusCode : String = info.code;
|
||||
|
||||
switch ( statusCode )
|
||||
{
|
||||
switch (statusCode) {
|
||||
case "NetConnection.Connect.Success":
|
||||
LogUtil.debug(NAME + ":Connection to viewers application succeeded.");
|
||||
|
||||
|
||||
startMonitoringBandwidth();
|
||||
|
||||
_netConnection.call(
|
||||
"getMyUserId",// Remote function name
|
||||
new Responder(
|
||||
@ -270,7 +268,6 @@ package org.bigbluebutton.main.model.users
|
||||
|
||||
private function autoReconnectTimerHandler(event:TimerEvent):void {
|
||||
LogUtil.debug(NAME + "autoReconnectTimerHandler: " + event);
|
||||
Alert.show("Attempting to reconnect");
|
||||
connect(_conferenceParameters, tried_tunneling);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
||||
import mx.core.UIComponent;
|
||||
import mx.events.CloseEvent;
|
||||
import mx.managers.PopUpManager;
|
||||
|
||||
import flash.geom.Point;
|
||||
import org.bigbluebutton.common.IBbbModuleWindow;
|
||||
import org.bigbluebutton.common.Images;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
@ -103,7 +103,8 @@
|
||||
[Bindable] private var fullscreen_icon:Class = images.full_screen;
|
||||
[Bindable] private var logs_icon:Class = images.table;
|
||||
[Bindable] private var reset_layout_icon:Class = images.layout;
|
||||
|
||||
[Bindable] private var statsIcon:Class = images.bandwidth;
|
||||
|
||||
private var receivedConfigLocaleVer:Boolean = false;
|
||||
private var receivedResourceLocaleVer:Boolean = false;
|
||||
|
||||
@ -357,7 +358,27 @@
|
||||
if (addedBtns.contains(event.button as UIComponent))
|
||||
addedBtns.removeChild(event.button as UIComponent);
|
||||
}
|
||||
|
||||
private var networkStatsWindow:NetworkStatsWindow = new NetworkStatsWindow();
|
||||
|
||||
private function openNetworkStatsWindow(e:Event = null):void {
|
||||
/*var btnPosition:Point = new Point(btnNetwork.x, btnNetwork.y);
|
||||
var btnPositionOnGlobal:Point = btnNetwork.localToGlobal(btnPosition);
|
||||
var windowPosition:Point = networkStatsWindow.globalToLocal(btnPositionOnGlobal);
|
||||
|
||||
windowPosition.x += btnNetwork.width + 10;
|
||||
windowPosition.y -= networkStatsWindow.height - 10;
|
||||
|
||||
networkStatsWindow.x = windowPosition.x;
|
||||
networkStatsWindow.y = windowPosition.y;*/
|
||||
|
||||
networkStatsWindow.appear();
|
||||
}
|
||||
|
||||
private function closeNetworkStatsWindow(e:Event = null):void {
|
||||
networkStatsWindow.disappear();
|
||||
}
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
|
||||
@ -374,6 +395,7 @@
|
||||
<mx:Label text="{isTunneling ? '[Tunnelling]' : ''}" id="isTunnellingLbl"/>
|
||||
<mx:Button width="20" height="20" visible="{layoutOptions.showLogButton}" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.logBtn.toolTip')}" id="logBtn" icon="{logs_icon}" click="openLogWindow()" />
|
||||
<!-- mx:Button width="20" height="20" visible="{layoutOptions.showResetLayout}" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.resetLayoutBtn.toolTip')}" id="btnResetLayout" icon="{reset_layout_icon}" click="resetLayout()" /-->
|
||||
<mx:Button id="btnNetwork" icon="{statsIcon}" width="20" height="20" mouseOver="openNetworkStatsWindow()" mouseOut="closeNetworkStatsWindow()" />
|
||||
<mx:HBox id="addedBtns" />
|
||||
</mx:ControlBar>
|
||||
</mx:VBox>
|
||||
|
@ -33,25 +33,25 @@
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import mx.core.UIComponent;
|
||||
|
||||
import org.bigbluebutton.common.IBbbToolbarComponent;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.common.events.CloseWindowEvent;
|
||||
import org.bigbluebutton.common.events.ToolbarButtonEvent;
|
||||
import org.bigbluebutton.core.BBB;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.ConfigEvent;
|
||||
import org.bigbluebutton.main.events.LogoutEvent;
|
||||
import org.bigbluebutton.main.events.SettingsEvent;
|
||||
import org.bigbluebutton.main.events.ShortcutEvent;
|
||||
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
|
||||
import org.bigbluebutton.main.model.LayoutOptions;
|
||||
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
|
||||
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||
import org.red5.flash.bwcheck.app.BandwidthDetectionApp;
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
import mx.core.UIComponent;
|
||||
import org.bigbluebutton.common.IBbbToolbarComponent;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.common.events.CloseWindowEvent;
|
||||
import org.bigbluebutton.common.events.OpenWindowEvent;
|
||||
import org.bigbluebutton.common.events.ToolbarButtonEvent;
|
||||
import org.bigbluebutton.core.BBB;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.ConfigEvent;
|
||||
import org.bigbluebutton.main.events.LogoutEvent;
|
||||
import org.bigbluebutton.main.events.SettingsEvent;
|
||||
import org.bigbluebutton.main.events.ShortcutEvent;
|
||||
import org.bigbluebutton.main.events.SuccessfulLoginEvent;
|
||||
import org.bigbluebutton.main.model.LayoutOptions;
|
||||
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
|
||||
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||
import org.bigbluebutton.core.services.BandwidthMonitor;
|
||||
|
||||
|
||||
private var DEFAULT_HELP_URL:String = "http://www.bigbluebutton.org/content/videos";
|
||||
|
||||
@ -161,29 +161,15 @@
|
||||
var d:Dispatcher = new Dispatcher();
|
||||
d.dispatchEvent(new ShortcutEvent(ShortcutEvent.OPEN_SHORTCUT_WIN));
|
||||
}
|
||||
|
||||
private var bwApp:BandwidthDetectionApp;
|
||||
|
||||
private function detectBandwidth():void {
|
||||
bwApp = new BandwidthDetectionApp();
|
||||
bwApp.serverURL = "demo.bigbluebutton.org";
|
||||
bwApp.serverApplication = "deskShare";
|
||||
bwApp.clientServerService = "checkBandwidthUp";
|
||||
bwApp.serverClientService = "checkBandwidth";
|
||||
bwApp.connect();
|
||||
}
|
||||
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
<mx:HBox id="addedBtns"/>
|
||||
<mx:Spacer width="100%"/>
|
||||
<views:LanguageSelector id="langSelector" visible="false" />
|
||||
<!--
|
||||
Some proof of concept to do BW check and reconnect.
|
||||
<mx:Button label="DISCONNECT!" click="BBB.initConnectionManager().forceClose()" height="22" toolTip="Click to simulate disconnection" />
|
||||
<mx:Button label="BW!" click="detectBandwidth()" height="22" toolTip="Click to simulate disconnection" />
|
||||
-->
|
||||
|
||||
<mx:Button label="{ResourceUtil.getInstance().getString('bbb.mainToolbar.shortcutBtn')}" click="onShortcutButtonClick()" height="22" toolTip="{ResourceUtil.getInstance().getString('bbb.mainToolbar.shortcutBtn.toolTip')}" />
|
||||
<mx:LinkButton id="helpBtn" label="{ResourceUtil.getInstance().getString('bbb.mainToolbar.helpBtn')}" visible="{showHelpBtn}" click="onHelpButtonClicked()" height="22"/>
|
||||
<mx:Button label="{ResourceUtil.getInstance().getString('bbb.mainToolbar.logoutBtn')}" id="btnLogout"
|
||||
|
@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
BigBlueButton 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 2.1 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/>.
|
||||
|
||||
Author: Felipe Cecagno <felipe@mconf.org>
|
||||
|
||||
$Id: $
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
title="Network monitor"
|
||||
creationComplete="onCreationComplete()"
|
||||
resizable="false"
|
||||
showCloseButton="false"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
width="210" height="261" minHeight="0" minWidth="0"
|
||||
resize="onResize()">
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flash.utils.Timer;
|
||||
|
||||
import org.bigbluebutton.common.events.CloseWindowEvent;
|
||||
import org.bigbluebutton.common.events.OpenWindowEvent;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.main.model.NetworkStatsData;
|
||||
|
||||
import mx.effects.Fade;
|
||||
import mx.events.EffectEvent;
|
||||
import mx.formatters.NumberFormatter;
|
||||
|
||||
private var _globalDispatcher:Dispatcher = new Dispatcher();
|
||||
private var _updateTimer:Timer = new Timer(1000);
|
||||
private var _numberFormatter:NumberFormatter = new NumberFormatter();
|
||||
|
||||
private function onCreationComplete():void {
|
||||
this.windowControls.maximizeRestoreBtn.visible = false;
|
||||
this.windowControls.minimizeBtn.visible = false;
|
||||
|
||||
this.x = parent.width - this.width;
|
||||
this.y = parent.height - this.height;
|
||||
|
||||
_numberFormatter.precision = 2;
|
||||
_numberFormatter.useThousandsSeparator = true;
|
||||
|
||||
_updateTimer.addEventListener(TimerEvent.TIMER, timerHandler);
|
||||
_updateTimer.start();
|
||||
}
|
||||
|
||||
private function timerHandler(e:TimerEvent):void {
|
||||
labelCurrentDownload.text = _numberFormatter.format(NetworkStatsData.getInstance().currentConsumedDownBW);
|
||||
labelTotalDownload.text = _numberFormatter.format(NetworkStatsData.getInstance().totalConsumedDownBW);
|
||||
labelAvailableDownload.text = _numberFormatter.format(NetworkStatsData.getInstance().measuredDownBW);
|
||||
labelDownloadLatency.text = String(NetworkStatsData.getInstance().measuredDownLatency);
|
||||
|
||||
labelCurrentUpload.text = _numberFormatter.format(NetworkStatsData.getInstance().currentConsumedUpBW);
|
||||
labelTotalUpload.text = _numberFormatter.format(NetworkStatsData.getInstance().totalConsumedUpBW);
|
||||
labelAvailableUpload.text = _numberFormatter.format(NetworkStatsData.getInstance().measuredUpBW);
|
||||
labelUploadLatency.text = String(NetworkStatsData.getInstance().measuredUpLatency);
|
||||
}
|
||||
|
||||
public function getPrefferedPosition():String {
|
||||
return MainCanvas.ABSOLUTE;
|
||||
}
|
||||
|
||||
private function onResize():void {
|
||||
LogUtil.debug("width=" + width + " height=" + height);
|
||||
}
|
||||
|
||||
public function appear():void {
|
||||
var fader:Fade = new Fade();
|
||||
fader.alphaFrom = 0;
|
||||
fader.alphaTo = 1;
|
||||
fader.duration = 500;
|
||||
fader.target = this;
|
||||
// fader.addEventListener(EffectEvent.EFFECT_START, function(e:EffectEvent):void {
|
||||
// var windowEvent:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
|
||||
// windowEvent.window = e.currentTarget as IBbbModuleWindow;
|
||||
// _globalDispatcher.dispatchEvent(windowEvent);
|
||||
// });
|
||||
fader.play();
|
||||
var windowEvent:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
|
||||
windowEvent.window = this;
|
||||
_globalDispatcher.dispatchEvent(windowEvent);
|
||||
this.windowManager.bringToFront(this);
|
||||
}
|
||||
|
||||
public function disappear():void {
|
||||
var fader:Fade = new Fade();
|
||||
fader.alphaFrom = 1;
|
||||
fader.alphaTo = 0;
|
||||
fader.duration = 500;
|
||||
fader.target = this;
|
||||
fader.addEventListener(EffectEvent.EFFECT_END, function(e:EffectEvent):void {
|
||||
var windowEvent:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
|
||||
windowEvent.window = e.target as IBbbModuleWindow;
|
||||
_globalDispatcher.dispatchEvent(windowEvent);
|
||||
});
|
||||
fader.play();
|
||||
}
|
||||
]]>
|
||||
</mx:Script>
|
||||
|
||||
|
||||
<mx:Panel width="100%" height="100%"
|
||||
paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10" headerHeight="10">
|
||||
<mx:VBox verticalGap="0" width="100%" height="100%">
|
||||
<mx:HBox backgroundColor="haloOrange" width="100%" horizontalAlign="center"><mx:Label fontWeight="bold" text="Upload"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Total: "/><mx:Label id="labelTotalUpload" fontWeight="bold" text="-"/><mx:Label text="MB"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Current: "/><mx:Label id="labelCurrentUpload" fontWeight="bold" text="-"/><mx:Label text="Kb/s"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Available: "/><mx:Label id="labelAvailableUpload" fontWeight="bold" text="-"/><mx:Label text="Mb/s"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Latency: "/><mx:Label id="labelUploadLatency" fontWeight="bold" text="-"/><mx:Label text="ms"/></mx:HBox>
|
||||
<mx:HBox backgroundColor="haloOrange" width="100%" horizontalAlign="center"><mx:Label fontWeight="bold" text="Download"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Total: "/><mx:Label id="labelTotalDownload" fontWeight="bold" text="-"/><mx:Label text="MB"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Current: "/><mx:Label id="labelCurrentDownload" fontWeight="bold" text="-"/><mx:Label text="Kb/s"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Available: "/><mx:Label id="labelAvailableDownload" fontWeight="bold" text="-"/><mx:Label text="Mb/s"/></mx:HBox>
|
||||
<mx:HBox horizontalGap="0"><mx:Label text="Latency: "/><mx:Label id="labelDownloadLatency" fontWeight="bold" text="-"/><mx:Label text="ms"/></mx:HBox>
|
||||
</mx:VBox>
|
||||
</mx:Panel>
|
||||
|
||||
</MDIWindow>
|
104
bigbluebutton-client/src/org/red5/flash/bwcheck/BandwidthDetection.as
Executable file → Normal file
104
bigbluebutton-client/src/org/red5/flash/bwcheck/BandwidthDetection.as
Executable file → Normal file
@ -1,53 +1,53 @@
|
||||
package org.red5.flash.bwcheck
|
||||
{
|
||||
import flash.events.EventDispatcher;
|
||||
import flash.net.NetConnection;
|
||||
import org.red5.flash.bwcheck.events.BandwidthDetectEvent;
|
||||
|
||||
[Event(name=BandwidthDetectEvent.DETECT_STATUS, type="org.red5.flash.bwcheck.events.BandwidthDetectEvent")]
|
||||
[Event(name=BandwidthDetectEvent.DETECT_COMPLETE, type="org.red5.flash.bwcheck.events.BandwidthDetectEvent")]
|
||||
|
||||
public class BandwidthDetection extends EventDispatcher
|
||||
{
|
||||
protected var nc:NetConnection;
|
||||
|
||||
public function BandwidthDetection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected function dispatch(info:Object, eventName:String):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(eventName);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
protected function dispatchStatus(info:Object):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(BandwidthDetectEvent.DETECT_STATUS);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
protected function dispatchComplete(info:Object):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(BandwidthDetectEvent.DETECT_COMPLETE);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
protected function dispatchFailed(info:Object):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(BandwidthDetectEvent.DETECT_FAILED);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
public function set connection(connect:NetConnection):void
|
||||
{
|
||||
nc = connect;
|
||||
}
|
||||
|
||||
}
|
||||
package org.red5.flash.bwcheck
|
||||
{
|
||||
import flash.events.EventDispatcher;
|
||||
import flash.net.NetConnection;
|
||||
import org.red5.flash.bwcheck.events.BandwidthDetectEvent;
|
||||
|
||||
[Event(name=BandwidthDetectEvent.DETECT_STATUS, type="org.red5.flash.bwcheck.events.BandwidthDetectEvent")]
|
||||
[Event(name=BandwidthDetectEvent.DETECT_COMPLETE, type="org.red5.flash.bwcheck.events.BandwidthDetectEvent")]
|
||||
|
||||
public class BandwidthDetection extends EventDispatcher
|
||||
{
|
||||
protected var nc:NetConnection;
|
||||
|
||||
public function BandwidthDetection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected function dispatch(info:Object, eventName:String):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(eventName);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
protected function dispatchStatus(info:Object):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(BandwidthDetectEvent.DETECT_STATUS);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
protected function dispatchComplete(info:Object):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(BandwidthDetectEvent.DETECT_COMPLETE);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
protected function dispatchFailed(info:Object):void
|
||||
{
|
||||
var event:BandwidthDetectEvent = new BandwidthDetectEvent(BandwidthDetectEvent.DETECT_FAILED);
|
||||
event.info = info;
|
||||
dispatchEvent(event);
|
||||
}
|
||||
|
||||
public function set connection(connect:NetConnection):void
|
||||
{
|
||||
nc = connect;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
286
bigbluebutton-client/src/org/red5/flash/bwcheck/ClientServerBandwidth.as
Executable file → Normal file
286
bigbluebutton-client/src/org/red5/flash/bwcheck/ClientServerBandwidth.as
Executable file → Normal file
@ -1,143 +1,143 @@
|
||||
package org.red5.flash.bwcheck
|
||||
{
|
||||
|
||||
import flash.net.Responder;
|
||||
|
||||
public class ClientServerBandwidth extends BandwidthDetection
|
||||
{
|
||||
|
||||
private var res:Responder;
|
||||
private var payload:Array = new Array();
|
||||
|
||||
private var latency:int = 0;
|
||||
private var cumLatency:int = 1;
|
||||
private var bwTime:int = 0;
|
||||
private var count:int = 0;
|
||||
private var sent:int = 0;
|
||||
private var kbitUp:int = 0;
|
||||
private var KBytes:int = 0;
|
||||
private var deltaUp:int = 0;
|
||||
private var deltaTime:int = 0;
|
||||
private var overhead:int = 0;
|
||||
private var pakInterval:int = 0;
|
||||
private var timePassed:int = 0;
|
||||
private var now:int = 0;
|
||||
|
||||
private var pakSent:Array = new Array();
|
||||
private var pakRecv:Array = new Array();
|
||||
private var beginningValues:Object = {};
|
||||
private var info:Object = new Object();
|
||||
|
||||
private var _service:String;
|
||||
|
||||
public function ClientServerBandwidth()
|
||||
{
|
||||
for (var i:int = 0; i < 1200; i++){
|
||||
payload[i] = Math.random(); //16K approx
|
||||
}
|
||||
|
||||
res = new Responder(onResult, onStatus);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function set service(service:String):void
|
||||
{
|
||||
_service = service;
|
||||
}
|
||||
|
||||
public function start():void
|
||||
{
|
||||
nc.client = this;
|
||||
var obj:Array = new Array();
|
||||
nc.call(_service, res);
|
||||
}
|
||||
|
||||
private function onResult(obj:Object):void
|
||||
{
|
||||
this.now = (new Date()).getTime()/1;
|
||||
if(sent == 0) {
|
||||
this.beginningValues = obj;
|
||||
this.beginningValues.time = now;
|
||||
this.pakSent[sent++] = now;
|
||||
nc.call(_service, res, now);
|
||||
} else {
|
||||
this.pakRecv[this.count] = now;
|
||||
this.pakInterval = (this.pakRecv[this.count] - this.pakSent[this.count])*1;
|
||||
this.count++;
|
||||
this.timePassed = (now - this.beginningValues.time);
|
||||
|
||||
if (this.count == 1) {
|
||||
this.latency = Math.min(timePassed, 800);
|
||||
this.latency = Math.max(this.latency, 10);
|
||||
this.overhead = obj.cOutBytes - this.beginningValues.cOutBytes;
|
||||
|
||||
this.pakSent[sent++] = now;
|
||||
nc.call(_service, res, now, payload);
|
||||
dispatchStatus(info);
|
||||
|
||||
}
|
||||
// If we have a hi-speed network with low latency send more to determine
|
||||
// better bandwidth numbers, send no more than 6 packets
|
||||
if ( (this.count >= 1) && (timePassed<1000))
|
||||
{
|
||||
this.pakSent[sent++] = now;
|
||||
this.cumLatency++;
|
||||
nc.call(_service, res, now, payload);
|
||||
dispatchStatus(info);
|
||||
} else if ( this.sent == this.count ) {
|
||||
// See if we need to normalize latency
|
||||
if ( this.latency >= 100 )
|
||||
{ // make sure we detect sattelite and modem correctly
|
||||
if ( this.pakRecv[1] - this.pakRecv[0] > 1000 )
|
||||
{
|
||||
this.latency = 100;
|
||||
}
|
||||
}
|
||||
payload = new Array();
|
||||
// Got back responses for all the packets compute the bandwidth.
|
||||
var stats:Object = obj;
|
||||
deltaUp = (stats.cOutBytes - this.beginningValues.cOutBytes)*8/1000;
|
||||
deltaTime = ((now - this.beginningValues.time) - (this.latency * this.cumLatency) )/1000;
|
||||
if ( deltaTime <= 0 )
|
||||
deltaTime = (now - this.beginningValues.time)/1000;
|
||||
|
||||
kbitUp = Math.round(deltaUp/deltaTime);
|
||||
KBytes = (stats.cOutBytes - this.beginningValues.cOutBytes)/1024;
|
||||
|
||||
var info:Object = new Object();
|
||||
info.kbitUp = kbitUp;
|
||||
info.deltaUp = deltaUp;
|
||||
info.deltaTime = deltaTime;
|
||||
info.latency = latency;
|
||||
info.KBytes = KBytes;
|
||||
|
||||
dispatchComplete(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override protected function dispatchStatus(obj:Object):void
|
||||
{
|
||||
obj.count = this.count;
|
||||
obj.sent = this.sent;
|
||||
obj.timePassed = timePassed;
|
||||
obj.latency = this.latency;
|
||||
obj.overhead = this.overhead;
|
||||
obj.pakInterval = this.pakInterval;
|
||||
obj.cumLatency = this.cumLatency;
|
||||
|
||||
super.dispatchStatus(info);
|
||||
}
|
||||
|
||||
private function onStatus(obj:Object):void
|
||||
{
|
||||
switch (obj.code)
|
||||
{
|
||||
case "NetConnection.Call.Failed":
|
||||
dispatchFailed(obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.red5.flash.bwcheck
|
||||
{
|
||||
|
||||
import flash.net.Responder;
|
||||
|
||||
public class ClientServerBandwidth extends BandwidthDetection
|
||||
{
|
||||
|
||||
private var res:Responder;
|
||||
private var payload:Array = new Array();
|
||||
|
||||
private var latency:int = 0;
|
||||
private var cumLatency:int = 1;
|
||||
private var bwTime:int = 0;
|
||||
private var count:int = 0;
|
||||
private var sent:int = 0;
|
||||
private var kbitUp:int = 0;
|
||||
private var KBytes:int = 0;
|
||||
private var deltaUp:int = 0;
|
||||
private var deltaTime:int = 0;
|
||||
private var overhead:int = 0;
|
||||
private var pakInterval:int = 0;
|
||||
private var timePassed:int = 0;
|
||||
private var now:int = 0;
|
||||
|
||||
private var pakSent:Array = new Array();
|
||||
private var pakRecv:Array = new Array();
|
||||
private var beginningValues:Object = {};
|
||||
private var info:Object = new Object();
|
||||
|
||||
private var _service:String;
|
||||
|
||||
public function ClientServerBandwidth()
|
||||
{
|
||||
for (var i:int = 0; i < 1200; i++){
|
||||
payload[i] = Math.random(); //16K approx
|
||||
}
|
||||
|
||||
res = new Responder(onResult, onStatus);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function set service(service:String):void
|
||||
{
|
||||
_service = service;
|
||||
}
|
||||
|
||||
public function start():void
|
||||
{
|
||||
nc.client = this;
|
||||
var obj:Array = new Array();
|
||||
nc.call(_service, res);
|
||||
}
|
||||
|
||||
private function onResult(obj:Object):void
|
||||
{
|
||||
this.now = (new Date()).getTime()/1;
|
||||
if(sent == 0) {
|
||||
this.beginningValues = obj;
|
||||
this.beginningValues.time = now;
|
||||
this.pakSent[sent++] = now;
|
||||
nc.call(_service, res, now);
|
||||
} else {
|
||||
this.pakRecv[this.count] = now;
|
||||
this.pakInterval = (this.pakRecv[this.count] - this.pakSent[this.count])*1;
|
||||
this.count++;
|
||||
this.timePassed = (now - this.beginningValues.time);
|
||||
|
||||
if (this.count == 1) {
|
||||
this.latency = Math.min(timePassed, 800);
|
||||
this.latency = Math.max(this.latency, 10);
|
||||
this.overhead = obj.cOutBytes - this.beginningValues.cOutBytes;
|
||||
|
||||
this.pakSent[sent++] = now;
|
||||
nc.call(_service, res, now, payload);
|
||||
dispatchStatus(info);
|
||||
|
||||
}
|
||||
// If we have a hi-speed network with low latency send more to determine
|
||||
// better bandwidth numbers, send no more than 6 packets
|
||||
if ( (this.count >= 1) && (timePassed<1000))
|
||||
{
|
||||
this.pakSent[sent++] = now;
|
||||
this.cumLatency++;
|
||||
nc.call(_service, res, now, payload);
|
||||
dispatchStatus(info);
|
||||
} else if ( this.sent == this.count ) {
|
||||
// See if we need to normalize latency
|
||||
if ( this.latency >= 100 )
|
||||
{ // make sure we detect sattelite and modem correctly
|
||||
if ( this.pakRecv[1] - this.pakRecv[0] > 1000 )
|
||||
{
|
||||
this.latency = 100;
|
||||
}
|
||||
}
|
||||
payload = new Array();
|
||||
// Got back responses for all the packets compute the bandwidth.
|
||||
var stats:Object = obj;
|
||||
deltaUp = (stats.cOutBytes - this.beginningValues.cOutBytes)*8/1000;
|
||||
deltaTime = ((now - this.beginningValues.time) - (this.latency * this.cumLatency) )/1000;
|
||||
if ( deltaTime <= 0 )
|
||||
deltaTime = (now - this.beginningValues.time)/1000;
|
||||
|
||||
kbitUp = Math.round(deltaUp/deltaTime);
|
||||
KBytes = (stats.cOutBytes - this.beginningValues.cOutBytes)/1024;
|
||||
|
||||
var info:Object = new Object();
|
||||
info.kbitUp = kbitUp;
|
||||
info.deltaUp = deltaUp;
|
||||
info.deltaTime = deltaTime;
|
||||
info.latency = latency;
|
||||
info.KBytes = KBytes;
|
||||
|
||||
dispatchComplete(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override protected function dispatchStatus(obj:Object):void
|
||||
{
|
||||
obj.count = this.count;
|
||||
obj.sent = this.sent;
|
||||
obj.timePassed = timePassed;
|
||||
obj.latency = this.latency;
|
||||
obj.overhead = this.overhead;
|
||||
obj.pakInterval = this.pakInterval;
|
||||
obj.cumLatency = this.cumLatency;
|
||||
|
||||
super.dispatchStatus(info);
|
||||
}
|
||||
|
||||
private function onStatus(obj:Object):void
|
||||
{
|
||||
switch (obj.code)
|
||||
{
|
||||
case "NetConnection.Call.Failed":
|
||||
dispatchFailed(obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
110
bigbluebutton-client/src/org/red5/flash/bwcheck/ServerClientBandwidth.as
Executable file → Normal file
110
bigbluebutton-client/src/org/red5/flash/bwcheck/ServerClientBandwidth.as
Executable file → Normal file
@ -1,55 +1,55 @@
|
||||
package org.red5.flash.bwcheck
|
||||
{
|
||||
import flash.net.Responder;
|
||||
|
||||
public class ServerClientBandwidth extends BandwidthDetection
|
||||
{
|
||||
|
||||
private var _service:String;
|
||||
private var info:Object = new Object();
|
||||
private var res:Responder;
|
||||
|
||||
public function ServerClientBandwidth()
|
||||
{
|
||||
res = new Responder(onResult, onStatus);
|
||||
}
|
||||
|
||||
public function onBWCheck(obj:Object):void
|
||||
{
|
||||
dispatchStatus(obj);
|
||||
}
|
||||
|
||||
public function onBWDone(obj:Object):void
|
||||
{
|
||||
dispatchComplete(obj);
|
||||
}
|
||||
|
||||
public function set service(service:String):void
|
||||
{
|
||||
_service = service;
|
||||
}
|
||||
|
||||
public function start():void
|
||||
{
|
||||
nc.client = this;
|
||||
nc.call(_service,res);
|
||||
}
|
||||
|
||||
private function onResult(obj:Object):void
|
||||
{
|
||||
dispatchStatus(obj);
|
||||
|
||||
}
|
||||
|
||||
private function onStatus(obj:Object):void
|
||||
{
|
||||
switch (obj.code)
|
||||
{
|
||||
case "NetConnection.Call.Failed":
|
||||
dispatchFailed(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.red5.flash.bwcheck
|
||||
{
|
||||
import flash.net.Responder;
|
||||
|
||||
public class ServerClientBandwidth extends BandwidthDetection
|
||||
{
|
||||
|
||||
private var _service:String;
|
||||
private var info:Object = new Object();
|
||||
private var res:Responder;
|
||||
|
||||
public function ServerClientBandwidth()
|
||||
{
|
||||
res = new Responder(onResult, onStatus);
|
||||
}
|
||||
|
||||
public function onBWCheck(obj:Object):void
|
||||
{
|
||||
dispatchStatus(obj);
|
||||
}
|
||||
|
||||
public function onBWDone(obj:Object):void
|
||||
{
|
||||
dispatchComplete(obj);
|
||||
}
|
||||
|
||||
public function set service(service:String):void
|
||||
{
|
||||
_service = service;
|
||||
}
|
||||
|
||||
public function start():void
|
||||
{
|
||||
nc.client = this;
|
||||
nc.call(_service,res);
|
||||
}
|
||||
|
||||
private function onResult(obj:Object):void
|
||||
{
|
||||
dispatchStatus(obj);
|
||||
|
||||
}
|
||||
|
||||
private function onStatus(obj:Object):void
|
||||
{
|
||||
switch (obj.code)
|
||||
{
|
||||
case "NetConnection.Call.Failed":
|
||||
dispatchFailed(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
266
bigbluebutton-client/src/org/red5/flash/bwcheck/app/BandwidthDetectionApp.as
Executable file → Normal file
266
bigbluebutton-client/src/org/red5/flash/bwcheck/app/BandwidthDetectionApp.as
Executable file → Normal file
@ -1,135 +1,131 @@
|
||||
package org.red5.flash.bwcheck.app
|
||||
{
|
||||
import flash.events.NetStatusEvent;
|
||||
import flash.net.NetConnection;
|
||||
import flash.net.Responder;
|
||||
|
||||
import mx.controls.TextArea;
|
||||
import mx.core.Application;
|
||||
|
||||
import org.red5.flash.bwcheck.ClientServerBandwidth;
|
||||
import org.red5.flash.bwcheck.ServerClientBandwidth;
|
||||
import org.red5.flash.bwcheck.events.BandwidthDetectEvent;
|
||||
|
||||
public class BandwidthDetectionApp
|
||||
{
|
||||
private var _serverURL:String = "localhost";
|
||||
private var _serverApplication:String = "";
|
||||
private var _clientServerService:String = "";
|
||||
private var _serverClientService:String = "";
|
||||
|
||||
private var nc:NetConnection;
|
||||
|
||||
public function BandwidthDetectionApp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function set serverURL(url:String):void
|
||||
{
|
||||
_serverURL = url;
|
||||
_serverURL = "demo.bigbluebutton.org";
|
||||
}
|
||||
|
||||
public function set serverApplication(app:String):void
|
||||
{
|
||||
_serverApplication = app;
|
||||
_serverApplication = "video";
|
||||
}
|
||||
|
||||
public function set clientServerService(service:String):void
|
||||
{
|
||||
_clientServerService = service;
|
||||
_clientServerService = "checkBandwidthUp";
|
||||
|
||||
}
|
||||
|
||||
public function set serverClientService(service:String):void
|
||||
{
|
||||
_serverClientService = service;
|
||||
_serverClientService = "checkBandwidth";
|
||||
}
|
||||
|
||||
public function connect():void
|
||||
{
|
||||
nc = new NetConnection();
|
||||
nc.objectEncoding = flash.net.ObjectEncoding.AMF0;
|
||||
nc.client = this;
|
||||
nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
|
||||
nc.connect("rtmpt://" + _serverURL + "/" + _serverApplication);
|
||||
}
|
||||
|
||||
|
||||
private function onStatus(event:NetStatusEvent):void
|
||||
{
|
||||
switch (event.info.code)
|
||||
{
|
||||
case "NetConnection.Connect.Success":
|
||||
trace("\n" + event.info.code);
|
||||
trace("\n Detecting Server Client Bandwidth \n\n");
|
||||
ServerClient();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function ClientServer():void
|
||||
{
|
||||
var clientServer:ClientServerBandwidth = new ClientServerBandwidth();
|
||||
//connect();
|
||||
clientServer.connection = nc;
|
||||
clientServer.service = _clientServerService;
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_COMPLETE,onClientServerComplete);
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_STATUS,onClientServerStatus);
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_FAILED,onDetectFailed);
|
||||
clientServer.start();
|
||||
}
|
||||
|
||||
public function ServerClient():void
|
||||
{
|
||||
var serverClient:ServerClientBandwidth = new ServerClientBandwidth();
|
||||
//connect();
|
||||
serverClient.connection = nc;
|
||||
serverClient.service = _serverClientService;
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_COMPLETE,onServerClientComplete);
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_STATUS,onServerClientStatus);
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_FAILED,onDetectFailed);
|
||||
|
||||
serverClient.start();
|
||||
}
|
||||
|
||||
public function onDetectFailed(event:BandwidthDetectEvent):void
|
||||
{
|
||||
trace("\n Detection failed with error: " + event.info.application + " " + event.info.description);
|
||||
}
|
||||
|
||||
public function onClientServerComplete(event:BandwidthDetectEvent):void
|
||||
{
|
||||
trace("\n\n kbitUp = " + event.info.kbitUp + ", deltaUp= " + event.info.deltaUp + ", deltaTime = " + event.info.deltaTime + ", latency = " + event.info.latency + " KBytes " + event.info.KBytes);
|
||||
trace("\n\n Client to Server Bandwidth Detection Complete");
|
||||
}
|
||||
|
||||
public function onClientServerStatus(event:BandwidthDetectEvent):void
|
||||
{
|
||||
if (event.info) {
|
||||
trace("\n count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" overhead: "+event.info.overhead+" packet interval: " + event.info.pakInterval + " cumLatency: " + event.info.cumLatency);
|
||||
}
|
||||
}
|
||||
|
||||
public function onServerClientComplete(event:BandwidthDetectEvent):void
|
||||
{
|
||||
trace("\n\n kbit Down: " + event.info.kbitDown + " Delta Down: " + event.info.deltaDown + " Delta Time: " + event.info.deltaTime + " Latency: " + event.info.latency);
|
||||
trace("\n\n Server Client Bandwidth Detect Complete");
|
||||
trace("\n\n Detecting Client Server Bandwidth\n\n");
|
||||
ClientServer();
|
||||
}
|
||||
|
||||
public function onServerClientStatus(event:BandwidthDetectEvent):void
|
||||
{
|
||||
if (event.info) {
|
||||
trace("\n count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" cumLatency: " + event.info.cumLatency);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
package org.red5.flash.bwcheck.app
|
||||
{
|
||||
import flash.events.NetStatusEvent;
|
||||
import flash.net.NetConnection;
|
||||
import flash.net.Responder;
|
||||
|
||||
import mx.core.Application;
|
||||
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
|
||||
import org.red5.flash.bwcheck.ClientServerBandwidth;
|
||||
import org.red5.flash.bwcheck.ServerClientBandwidth;
|
||||
import org.red5.flash.bwcheck.events.BandwidthDetectEvent;
|
||||
|
||||
public class BandwidthDetectionApp extends Application
|
||||
{
|
||||
private var _serverURL:String = "localhost";
|
||||
private var _serverApplication:String = "";
|
||||
private var _clientServerService:String = "";
|
||||
private var _serverClientService:String = "";
|
||||
|
||||
private var nc:NetConnection;
|
||||
|
||||
public function BandwidthDetectionApp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function set serverURL(url:String):void
|
||||
{
|
||||
_serverURL = url;
|
||||
}
|
||||
|
||||
public function set serverApplication(app:String):void
|
||||
{
|
||||
_serverApplication = app;
|
||||
}
|
||||
|
||||
public function set clientServerService(service:String):void
|
||||
{
|
||||
_clientServerService = service;
|
||||
}
|
||||
|
||||
public function set serverClientService(service:String):void
|
||||
{
|
||||
_serverClientService = service;
|
||||
}
|
||||
|
||||
public function connect():void
|
||||
{
|
||||
nc = new NetConnection();
|
||||
nc.objectEncoding = flash.net.ObjectEncoding.AMF0;
|
||||
nc.client = this;
|
||||
nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
|
||||
nc.connect("rtmp://" + _serverURL + "/" + _serverApplication);
|
||||
}
|
||||
|
||||
|
||||
private function onStatus(event:NetStatusEvent):void
|
||||
{
|
||||
switch (event.info.code)
|
||||
{
|
||||
case "NetConnection.Connect.Success":
|
||||
LogUtil.debug(event.info.code);
|
||||
LogUtil.debug("Detecting Server Client Bandwidth");
|
||||
ServerClient();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function ClientServer():void
|
||||
{
|
||||
var clientServer:ClientServerBandwidth = new ClientServerBandwidth();
|
||||
//connect();
|
||||
clientServer.connection = nc;
|
||||
clientServer.service = _clientServerService;
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_COMPLETE,onClientServerComplete);
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_STATUS,onClientServerStatus);
|
||||
clientServer.addEventListener(BandwidthDetectEvent.DETECT_FAILED,onDetectFailed);
|
||||
clientServer.start();
|
||||
}
|
||||
|
||||
public function ServerClient():void
|
||||
{
|
||||
var serverClient:ServerClientBandwidth = new ServerClientBandwidth();
|
||||
//connect();
|
||||
serverClient.connection = nc;
|
||||
serverClient.service = _serverClientService;
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_COMPLETE,onServerClientComplete);
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_STATUS,onServerClientStatus);
|
||||
serverClient.addEventListener(BandwidthDetectEvent.DETECT_FAILED,onDetectFailed);
|
||||
|
||||
serverClient.start();
|
||||
}
|
||||
|
||||
public function onDetectFailed(event:BandwidthDetectEvent):void
|
||||
{
|
||||
LogUtil.debug("Detection failed with error: " + event.info.application + " " + event.info.description);
|
||||
}
|
||||
|
||||
public function onClientServerComplete(event:BandwidthDetectEvent):void
|
||||
{
|
||||
LogUtil.debug("kbitUp = " + event.info.kbitUp + ", deltaUp= " + event.info.deltaUp + ", deltaTime = " + event.info.deltaTime + ", latency = " + event.info.latency + " KBytes " + event.info.KBytes);
|
||||
LogUtil.debug("Client to Server Bandwidth Detection Complete");
|
||||
}
|
||||
|
||||
public function onClientServerStatus(event:BandwidthDetectEvent):void
|
||||
{
|
||||
if (event.info) {
|
||||
LogUtil.debug("count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" overhead: "+event.info.overhead+" packet interval: " + event.info.pakInterval + " cumLatency: " + event.info.cumLatency);
|
||||
}
|
||||
}
|
||||
|
||||
public function onServerClientComplete(event:BandwidthDetectEvent):void
|
||||
{
|
||||
LogUtil.debug("kbit Down: " + event.info.kbitDown + " Delta Down: " + event.info.deltaDown + " Delta Time: " + event.info.deltaTime + " Latency: " + event.info.latency);
|
||||
LogUtil.debug("Server Client Bandwidth Detect Complete");
|
||||
LogUtil.debug("Detecting Client Server Bandwidth)";
|
||||
ClientServer();
|
||||
}
|
||||
|
||||
public function onServerClientStatus(event:BandwidthDetectEvent):void
|
||||
{
|
||||
if (event.info) {
|
||||
LogUtil.debug("count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" cumLatency: " + event.info.cumLatency);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
58
bigbluebutton-client/src/org/red5/flash/bwcheck/events/BandwidthDetectEvent.as
Executable file → Normal file
58
bigbluebutton-client/src/org/red5/flash/bwcheck/events/BandwidthDetectEvent.as
Executable file → Normal file
@ -1,30 +1,30 @@
|
||||
package org.red5.flash.bwcheck.events
|
||||
{
|
||||
import flash.events.Event;
|
||||
|
||||
public class BandwidthDetectEvent extends Event
|
||||
{
|
||||
public static const DETECT_STATUS:String = "detect_status";
|
||||
public static const DETECT_COMPLETE:String = "detect_complete";
|
||||
public static const DETECT_FAILED:String = "detect_failed";
|
||||
|
||||
private var _info:Object;
|
||||
|
||||
public function BandwidthDetectEvent(eventName:String)
|
||||
{
|
||||
super (eventName);
|
||||
}
|
||||
|
||||
public function set info(obj:Object):void
|
||||
{
|
||||
_info = obj;
|
||||
}
|
||||
|
||||
public function get info():Object
|
||||
{
|
||||
return _info;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
package org.red5.flash.bwcheck.events
|
||||
{
|
||||
import flash.events.Event;
|
||||
|
||||
public class BandwidthDetectEvent extends Event
|
||||
{
|
||||
public static const DETECT_STATUS:String = "detect_status";
|
||||
public static const DETECT_COMPLETE:String = "detect_complete";
|
||||
public static const DETECT_FAILED:String = "detect_failed";
|
||||
|
||||
private var _info:Object;
|
||||
|
||||
public function BandwidthDetectEvent(eventName:String)
|
||||
{
|
||||
super (eventName);
|
||||
}
|
||||
|
||||
public function set info(obj:Object):void
|
||||
{
|
||||
_info = obj;
|
||||
}
|
||||
|
||||
public function get info():Object
|
||||
{
|
||||
return _info;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user