Charlie from Wowza Media Server has been working on porting over the FMS bandwidth detection to Java. You should check it out and dialoge with him to see if together you can come up with a complete solution. See the following forum thread:
http://www.wowzamedia.com/forums/showthread.php?t=102 HTH, Aaron Roberson On 2/15/07, Dan Rossi <[EMAIL PROTECTED]> wrote: > Hi i was wondering if any Java ppl have managed to check this out, am i > on the right track or wasting my time ? Is there a better way to send > the payload to do the bandwidth testing. Let me know. > > Dan Rossi wrote: > > Just thought id resend just in case people thought it was a question. > > > > Dan Rossi wrote: > > > >> 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 :) > >> > >> //example > >> public boolean appConnect(IConnection conn) { > >> > >> BandwidthDetection detect = new BandwidthDetection(); > >> detect.checkBandwidth(conn); > >> } > >> > >> 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 java.util.Date; > >> import java.util.Map; > >> import java.util.HashMap; > >> > >> public class BandwidthDetection implements IPendingServiceCallback { > >> > >> private long bytes_in = 0; > >> private long msg_in; > >> private long bytes_out; > >> private long msg_out; > >> private long msg_dropped; > >> private long ping_rtt; > >> > >> private int latency = 0; > >> private int cumLatency = 1; > >> private int bwTime = 0; > >> private int count = 0; > >> private int sent = 0; > >> private Object client; > >> private long now; > >> private long[] pakSent = new long[1200]; > >> private long[] pakRecv = new long[1200]; > >> private Map<String, Long> beginningValues; > >> private double[] payload = new double[1200]; > >> > >> public BandwidthDetection() > >> { > >> pakSent = new long[1200]; > >> pakRecv = new long[1200]; > >> payload = new double[1200]; > >> } > >> > >> public void checkBandwidth(Object client) > >> { > >> this.calculateClientBw(client); > >> } > >> > >> private void calculateClientBw(Object client) > >> { > >> > >> for (int i=0; i<1200; i++){ > >> payload[i] = Math.random(); //16K approx > >> } > >> > >> this.getStats(); > >> > >> this.client = client; > >> long now = (new Date().getTime()/1); > >> > >> Map<String, Long> map = new HashMap<String, Long>(); > >> map.put("b_down", this.bytes_out); > >> map.put("b_up", this.bytes_in); > >> map.put("time", now); > >> this.beginningValues = map; > >> > >> System.out.println(now); > >> > >> pakSent[this.sent++] = now; > >> > >> this.callBWCheck(""); > >> > >> this.pakSent[this.sent++] = now; > >> > >> this.callBWCheck(this.payload); > >> > >> } > >> > >> > >> private void callBWCheck(Object params) > >> { > >> IConnection conn = Red5.getConnectionLocal(); > >> > >> if (conn instanceof IServiceCapableConnection) { > >> ((IServiceCapableConnection) conn).invoke("onBWCheck", new > >> Object[]{params}, this); > >> //log.info("sending notification to "+conn); > >> } > >> } > >> > >> private void callBWDone(double kbitDown, long deltaDown, double > >> deltaTime, int latency) > >> { > >> IConnection conn = Red5.getConnectionLocal(); > >> > >> if (conn instanceof IServiceCapableConnection) { > >> ((IServiceCapableConnection) conn).invoke("onBWDone", new > >> Object[]{kbitDown, deltaDown, deltaTime, latency}); > >> //log.info("sending notification to "+conn); > >> } > >> } > >> > >> private void getStats() > >> { > >> IConnection conn = Red5.getConnectionLocal(); > >> > >> if (conn instanceof IStreamCapableConnection) { > >> IStreamCapableConnection streamConn = > >> (IStreamCapableConnection) conn; > >> bytes_in = streamConn.getReadBytes(); > >> msg_in = streamConn.getReadMessages(); > >> bytes_out = streamConn.getWrittenBytes(); > >> msg_out = streamConn.getWrittenMessages(); > >> msg_dropped = streamConn.getDroppedMessages(); > >> ping_rtt = streamConn.getLastPingTime(); > >> } > >> > >> } > >> > >> > >> /** > >> * Handle callback from service call. > >> */ > >> > >> public void resultReceived(IPendingServiceCall call) { > >> long now = (new Date()).getTime()/1; > >> this.pakRecv[this.count] = now; > >> this.count++; > >> int timePassed = (int)(now - this.beginningValues.get("time")); > >> > >> if (this.count == 1) { > >> > >> this.latency = Math.min(timePassed, 800); > >> > >> this.latency = Math.max(this.latency, 10); > >> > >> } > >> > >> //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 == 2 && (timePassed<2000)) > >> { > >> > >> this.pakSent[this.sent++] = now; > >> this.cumLatency++; > >> this.callBWCheck(this.payload); > >> > >> //this.client.call("onBWCheck", res, this.client.payload); > >> } 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; > >> } > >> > >> } > >> > >> > >> this.payload = new double[0]; > >> //delete this.client.payload; > >> > >> // Got back responses for all the packets compute the > >> bandwidth. > >> this.getStats(); > >> > >> long deltaDown = this.bytes_out - > >> this.beginningValues.get("b_down")*8/1000; > >> double deltaTime = ( (now - > >> this.beginningValues.get("time")) - (this.latency*this.cumLatency))/1000; > >> > >> if (deltaTime <= 0) deltaTime = (now - > >> this.beginningValues.get("time"))/1000; > >> //System.out.println(deltaDown + " " + this.bytes_out + " " > >> + this.beginningValues.get("b_down") + " " + deltaTime + " " + (now - > >> this.beginningValues.get("time")) + " " + (this.latency*this.cumLatency)); > >> > >> double kbitDown = deltaDown/deltaTime; > >> > >> System.out.println("onBWDone: kbitDown = " + kbitDown + ", > >> deltaDown= " + deltaDown + ", deltaTime = " + deltaTime + ", latency = " > >> + this.latency + "KBytes " + (this.bytes_out - > >> this.beginningValues.get("b_down"))/1024); > >> > >> this.callBWDone(kbitDown, deltaDown, deltaTime, this.latency); > >> } > >> > >> } > >> > >> > >> > >> } > >> > >> _______________________________________________ > >> Red5 mailing list > >> [email protected] > >> http://osflash.org/mailman/listinfo/red5_osflash.org > >> > >> > >> > > > > > > _______________________________________________ > > Red5 mailing list > > [email protected] > > http://osflash.org/mailman/listinfo/red5_osflash.org > > > > > > > _______________________________________________ > Red5 mailing list > [email protected] > http://osflash.org/mailman/listinfo/red5_osflash.org > _______________________________________________ Red5 mailing list [email protected] http://osflash.org/mailman/listinfo/red5_osflash.org
