Code:Server bandwidthdetection

From Red5Tutorials

Jump to: navigation, search

Port of bandwidth detection from FMS to Red5 by Dan Rossi (2007/02/08)

Dan writes: Hi there ive taken the initiative because i cant seem to find any other solution out there to port the FMS code. Ive prob made alot of mistakes in terms of the HashMap and arrays. I had to also port the client.getStats method from FMS which returns information in methods returned from red5 but not easily accessible via variables, maybe there is a better way of accessing this until the stats API is avail ?

Basically all it does is send a packet array and calculate the result time to work out the download rate or something like that ? Ive yet to manage to get the right calculation for the download rate as i was testing it locally, i dont think that one is right. If someone wants to clean it up go ahead :)

Port of bandwidth detection from FMS to Red5 by Dan Rossi (2007/03/23)

Dan Writes: "Hi it seems there has been an update on the wowza list to the bandwidth detection source, the current implementation sends packets 3 times which creates a tiny lag on startup, the calculations are more correct, so ive migrated and merged some of the code. Full credits here

http://www.wowzamedia.com/forums/showthread.php?t=169

Ive supplied a quick flex example and tarball source code aswell as the flex source, it would be good to find out how to optimise it a little better, maybe a better way to send AMF packet byte data, aswell as storing the hashmaps with the stats information for the beginning and end. Finally it would be good to implement into a bean you just add into the xml config and it does the bandwidth detection in the onconnect method ?

If you keep refreshing you may see that the numbers vary so its not enitely exact. It would be good to know if there is a network framework that is capable of doing these kind of calculations ? As this code still seems abit clunky and can be better as it was a port from the FMS code to begin with anyway.

http://www.electroteque.org:5080/bwcheck/bwcheck.html http://www.electroteque.org:5080/bwcheck/bwcheck.mxml http://www.electroteque.org:5080/bwcheck/bwcheck.tar.gz "


Calling example

public boolean appConnect(IConnection conn) {
       
        BandwidthDetection detect = new BandwidthDetection();
        detect.checkBandwidth(conn);
}

Class IBandwidthDetection.java

import org.red5.server.api.IConnection;

public interface IBandwidthDetection {
       
   public void checkBandwidth(IConnection p_client);
       
   public void calculateClientBw(IConnection p_client);
}

Class BandwidthDetection.java:

import org.red5.server.api.IConnection;
import org.red5.server.api.Red5;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.server.api.service.IServiceCapableConnection;
import org.red5.server.api.stream.IStreamCapableConnection;

import org.apache.log4j.Logger;

import java.util.*;

import java.util.Map;
import java.util.HashMap;

public class BandwidthDetection implements IPendingServiceCallback, IBandwidthDetection {
   
   IConnection client = null;
   double latency = 0;
   double cumLatency = 1;
   int count = 0;
   int sent = 0;
   double kbitDown = 0;
   double deltaDown = 0;
   double deltaTime = 0;
   
   List<Long> pakSent = new ArrayList<Long>();
   List<Long> pakRecv = new ArrayList<Long>();
   
   private Map<String, Long> beginningValues;
   private double[] payload = new double[1200];
   private double[] payload_1 = new double[12000];
   private double[] payload_2 = new double[12000];
   
   private static final Logger log = Logger.getLogger(BandwidthDetection.class.getName());
   
   public BandwidthDetection()
   {
       
   }
   
   public void checkBandwidth(IConnection p_client)
   {
       this.calculateClientBw(p_client);
   }
   
   public void calculateClientBw(IConnection p_client)
   {
       for (int i=0; i<1200; i  ){
           payload[i] = Math.random();
       }
       
       p_client.setAttribute("payload", payload);
       
       for (int i=0; i<12000; i  ){
           payload_1[i] = Math.random();
       }
       
       p_client.setAttribute("payload_1", payload_1);
       
       for (int i=0; i<12000; i  ){
           payload_2[i] = Math.random();
       }
       
       p_client.setAttribute("payload_2", payload_2);
       
       final IStreamCapableConnection beginningStats = this.getStats();
       final Long start = new Long(System.nanoTime()/1000000); //new Long(System.currentTimeMillis());
       
       this.client = p_client;
       beginningValues = new HashMap<String, Long>();
       beginningValues.put("b_down", beginningStats.getWrittenBytes());
       beginningValues.put("b_up", beginningStats.getReadBytes());
       beginningValues.put("time", start);
       
       this.pakSent.add(start);
       this.sent  ;
       this.callBWCheck("");
   }
   
   /**
    * Handle callback from service call. 
    */
   public void resultReceived(IPendingServiceCall call) { 
       Long now = new Long(System.nanoTime()/1000000); //new Long(System.currentTimeMillis());
       this.pakRecv.add(now);
       Long timePassed = (now - this.beginningValues.get("time"));
       this.count  ;
       
       if (count == 1) {
           latency = Math.min(timePassed, 800);
           latency = Math.max(latency, 10);
           
           log.info("count: " count  " sent: " sent " timePassed: " timePassed " latency: " latency);
           
           // We now have a latency figure so can start sending test data.
           // Second call.  1st packet sent
           pakSent.add(now);
           sent  ;
           
           this.callBWCheck(this.client.getAttribute("payload"));
       }
       // To run a very quick test, uncomment the following if statement and comment out the next 3 if statements.
       /*
       else if (count == 2
Personal tools