the NetworkStatsWindow is already presenting the measured bandwidth up/down between client and server; still need to figure out a better way to present the window into the screen

This commit is contained in:
Felipe Cecagno 2012-12-08 18:45:00 -02:00
parent b4f36b894c
commit 1523774a1c
13 changed files with 522 additions and 475 deletions

View File

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

View File

@ -1,22 +1,28 @@
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 = "";
private var _clientServerService:String = "";
private var _serverClientService:String = "";
private var _serverApplication:String = "video";
private var _clientServerService:String = "checkBandwidthUp";
private var _serverClientService:String = "checkBandwidth";
private var nc:NetConnection;
private var bwTestTimer:Timer = new Timer(1000, 1);
private var bwTestTimer:Timer;
public function BandwidthMonitor() {
@ -29,16 +35,7 @@ package org.bigbluebutton.core.services
public function set serverApplication(app:String):void {
_serverApplication = app;
}
public function set clientServerService(service:String):void {
_clientServerService = "checkBandwidthUp";
}
public function set serverClientService(service:String):void {
_serverClientService = "checkBandwidth";
}
public function start():void {
connect();
}
@ -48,31 +45,38 @@ package org.bigbluebutton.core.services
nc.objectEncoding = flash.net.ObjectEncoding.AMF0;
nc.client = this;
nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
nc.connect("rtmpt://" + _serverURL + "/" + _serverApplication);
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":
trace("\n" + event.info.code);
// trace("\n Detecting Server Client Bandwidth \n\n");
LogUtil.debug("Starting to monitor bandwidth between client and server");
monitor();
break;
break;
default:
LogUtil.debug("Cannot establish the connection to measure bandwidth");
break;
}
}
private function monitor():void {
trace("Starting to monitor bandwidth");
LogUtil.debug("Starting to monitor bandwidth");
bwTestTimer = new Timer(30000);
bwTestTimer.addEventListener(TimerEvent.TIMER, rtmptRetryTimerHandler);
bwTestTimer.start();
}
private function rtmptRetryTimerHandler(event:TimerEvent):void {
trace("Starting to detect bandwidth from server to client.");
LogUtil.debug("Starting to detect bandwidth from server to client");
ServerClient();
}
@ -97,40 +101,44 @@ package org.bigbluebutton.core.services
serverClient.addEventListener(BandwidthDetectEvent.DETECT_COMPLETE,onServerClientComplete);
serverClient.addEventListener(BandwidthDetectEvent.DETECT_STATUS,onServerClientStatus);
serverClient.addEventListener(BandwidthDetectEvent.DETECT_FAILED,onDetectFailed);
trace("Monitoring client.");
serverClient.start();
}
public function onDetectFailed(event:BandwidthDetectEvent):void
{
trace("\n Detection failed with error: " + event.info.application + " " + event.info.description);
LogUtil.debug("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");
{
// 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) {
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);
// 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
{
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");
// 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) {
trace("\n count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" cumLatency: " + event.info.cumLatency);
// LogUtil.debug("\n count: "+event.info.count+ " sent: "+event.info.sent+" timePassed: "+event.info.timePassed+" latency: "+event.info.latency+" cumLatency: " + event.info.cumLatency);
}
}
}

View File

@ -1,4 +1,4 @@
package org.bigbluebutton.core.managers
package org.bigbluebutton.core.services
{
import com.asfusion.mate.events.Dispatcher;
@ -18,7 +18,7 @@ package org.bigbluebutton.core.managers
import org.bigbluebutton.main.events.NetworkStatsEvent;
import org.bigbluebutton.main.model.NetworkStatsData;
public class StreamManager
public class StreamMonitor
{
/**
* https://github.com/ritzalam/red5-bw-check
@ -40,7 +40,7 @@ package org.bigbluebutton.core.managers
private var _globalDispatcher:Dispatcher = new Dispatcher();
private var _totalBytesCounter:Dictionary = new Dictionary();
public function StreamManager():void {
public function StreamMonitor():void {
//Create NetMonitor object
_netmon = new NetMonitor();
_netmon.addEventListener( NetMonitorEvent.NET_STREAM_CREATE, newNetStream );
@ -115,7 +115,7 @@ package org.bigbluebutton.core.managers
for (var i:int = 0; i < streams.length; i++) {
if (streams[i] == null || streams[i].info == null) {
log("Stream info is null, returning");
// stream info is null, returning
continue;
}
@ -206,7 +206,7 @@ package org.bigbluebutton.core.managers
}
private function log(s:String):void {
LogUtil.debug("[StreamManager] " + s);
LogUtil.debug("[StreamMonitor] " + s);
}
}
}

View File

@ -31,7 +31,7 @@
<ObjectBuilder generator="{ModulesProxy}" cache="global" />
<ObjectBuilder generator="{UserService}" cache="global" />
<ObjectBuilder generator="{ConfigManager}" cache="global" />
<ObjectBuilder generator="{StreamManager}" cache="global" />
<ObjectBuilder generator="{StreamMonitor}" cache="global" />
</EventHandlers>
<EventHandlers type="{PortTestEvent.TEST_RTMP}" >
@ -111,8 +111,8 @@
import mx.events.FlexEvent;
import org.bigbluebutton.core.managers.ConfigManager;
import org.bigbluebutton.core.managers.StreamManager;
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;

View File

@ -15,6 +15,10 @@ package org.bigbluebutton.main.model
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.
@ -47,6 +51,31 @@ package org.bigbluebutton.main.model
_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;
}
@ -63,6 +92,21 @@ package org.bigbluebutton.main.model
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;
}
}
}

View File

@ -177,7 +177,9 @@ package org.bigbluebutton.main.model.users
private function startMonitoringBandwidth():void {
trace("Start monitoring bandwidth.");
_bwMon.serverURL = "192.168.0.249";
var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
var result:Array = pattern.exec(_applicationURI);
_bwMon.serverURL = result.server;
_bwMon.serverApplication = "video";
_bwMon.start();
}
@ -192,7 +194,7 @@ package org.bigbluebutton.main.model.users
case "NetConnection.Connect.Success":
LogUtil.debug(NAME + ":Connection to viewers application succeeded.");
// startMonitoringBandwidth();
startMonitoringBandwidth();
_netConnection.call(
"getMyUserId",// Remote function name

View File

@ -52,7 +52,7 @@
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 org.bigbluebutton.core.services.BandwidthMonitor;
private var DEFAULT_HELP_URL:String = "http://www.bigbluebutton.org/content/videos";
@ -163,17 +163,6 @@
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"/>
@ -181,9 +170,7 @@
<views:LanguageSelector id="langSelector" visible="false" />
<!--
<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"

View File

@ -28,8 +28,9 @@
title="Network monitor"
creationComplete="onCreationComplete()"
resizable="false"
showCloseButton="false"
implements="org.bigbluebutton.common.IBbbModuleWindow"
width="210" height="185" minHeight="0" minWidth="0"
width="210" height="261" minHeight="0" minWidth="0"
resize="onResize()">
<mx:Script>
@ -56,8 +57,8 @@
this.windowControls.maximizeRestoreBtn.visible = false;
this.windowControls.minimizeBtn.visible = false;
this.x = parent.width - this.width;
this.y = 0;
this.x = parent.width - this.width;
this.y = parent.height - this.height;
_numberFormatter.precision = 2;
_numberFormatter.useThousandsSeparator = true;
@ -69,8 +70,13 @@
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 {
@ -96,6 +102,7 @@
var windowEvent:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
windowEvent.window = this;
_globalDispatcher.dispatchEvent(windowEvent);
this.windowManager.bringToFront(this);
}
public function disappear():void {
@ -119,11 +126,15 @@
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="0"/><mx:Label text="MB"/></mx:HBox>
<mx:HBox horizontalGap="0"><mx:Label text="Current: "/><mx:Label id="labelCurrentUpload" fontWeight="bold" text="0"/><mx:Label text="Kb/s"/></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="0"/><mx:Label text="MB"/></mx:HBox>
<mx:HBox horizontalGap="0"><mx:Label text="Current: "/><mx:Label id="labelCurrentDownload" fontWeight="bold" text="0"/><mx:Label text="Kb/s"/></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>

View 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;
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}
}

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

View 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;
}
}
}