2015-08-03 12 views
9

Ich verwende eine Downloader-Klasse, um große Dateien von einem IIS-Server auf WS2012 zu erhalten und den Download-Fortschritt zu verarbeiten.AIR AS3-Dateidownload ist beschädigt, wenn die Bandbreite niedrig ist

Es funktioniert gut, aber wenn die Bandbreite des Clients zu gesättigt ist, werden Progress-Ereignisse nicht mehr ausgelöst und nach einer gewissen Zeit stoppt der Download (das Complete-Ereignis scheint ausgelöst zu werden), trotz des Downloads unvollendet, den Client mit einer beschädigten Datei verlassen.

ich nicht herausfinden konnte, wie dieses Problem zu lösen, oder sogar, was Strategie sollte ich auf dieses Problem (den Download beenden und einen Fehler an? Für die Bandbreitenverfügbarkeit Warten Sie auf mein nächstes Stück Bytes zu bekommen?) Nehmen

Hier ist die Downloader.as Klasse

public class Downloader extends EventDispatcher 
{ 
    [Event(name="DownloadComplete", type="DownloadEvent")] 

    public static var spd:int = 0; 
    private var file:File; 
    private var fileStream:FileStream; 
    private var url:String; 
    private var urlStream:URLStream; 

    var mc_background:MovieClip; 
    var howManyTimes:Number = 3; //How many times per second the download speed will be traced 
    var bytesLoaded:Number = 0; //don't change, necessary for calculation 
    var lastTime:int = 0; //don't change, necessary for calculation 


    private var waitingForDataToWrite:Boolean = false; 

    public function Downloader(s:MovieClip) 
    { 
     mc_background = s; 

     lastTime = getTimer(); 
     urlStream = new URLStream(); 

     urlStream.addEventListener(Event.OPEN, onOpenEvent); 
     urlStream.addEventListener(ProgressEvent.PROGRESS, onProgressEvent); 
     urlStream.addEventListener(Event.COMPLETE, onCompleteEvent); 

     fileStream = new FileStream(); 
     fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeProgressHandler) 

    } 

    public function download(formUrl:String, toFile:File):void { 
     this.url = formUrl; 
     this.file = toFile; 
     mc_background.pb.file_txt.text = file.name; 
     fileStream.openAsync(file, FileMode.WRITE); 
     urlStream.load(new URLRequest(url)); 
    } 

    private function onOpenEvent(event:Event):void { 
     waitingForDataToWrite = true; 

     dispatchEvent(event.clone()); 
    } 

    private function onProgressEvent(event:ProgressEvent):void { 
     var time:int = getTimer(); 
     if(time - lastTime >= (1000/howManyTimes)) 
     { 
      var kiloBytes:Number = (event.bytesLoaded - bytesLoaded)/1000; 
      var timeInSecs:Number = (time - lastTime)/1000; 

      var kbsPerSecVal:Number = Math.floor(kiloBytes/timeInSecs); 
      trace(kbsPerSecVal + " kbs/s"); 

      mc_background.pb.speed_txt.text = kbsPerSecVal + " kbs/s"; 
      bytesLoaded = event.bytesLoaded; 
      lastTime = getTimer(); 
     } 
     if(waitingForDataToWrite){ 
      writeToDisk(); 
      dispatchEvent(event.clone()); 
     } 
    } 

    private function writeToDisk():void { 
     var fileData:ByteArray = new ByteArray(); 
     urlStream.readBytes(fileData, 0, urlStream.bytesAvailable); 
     fileStream.writeBytes(fileData,0,fileData.length); 
     waitingForDataToWrite = false; 

     dispatchEvent(new DataEvent(DataEvent.DATA)); 
    } 

    private function writeProgressHandler(evt:OutputProgressEvent):void{ 
     waitingForDataToWrite = true; 
    } 

    private function onCompleteEvent(event:Event):void { 
     if(urlStream.bytesAvailable>0) 
      writeToDisk(); 
     fileStream.close(); 

     fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeProgressHandler); 

     dispatchEvent(event.clone()); 
     // dispatch additional DownloadEvent 
     dispatchEvent(new DownloadEvent(DownloadEvent.DOWNLOAD_COMPLETE, url, file)); 
    } 

} 
+3

Ich kann das Verhalten nicht erklären nur einige Vorschläge, um damit umzugehen .. '..finish den Download und einen Fehler anzeigen? Oder warte auf die Verfügbarkeit der Bandbreite, um mein nächstes Byte zu bekommen? "Nun, warum nicht beides? Wenn es ein Problem gibt, rufen Sie die Meldung "Ein Netzwerkfehler verursachte einen unvollständigen Download" hervor ** an dieser Stelle zeigen Sie 2 Tasten: "Download fortsetzen" oder "Behalten Sie, was ich habe" .. Wenn Sie fortfahren möchten, können Sie lesen ** [this] (http://richapps.de/resumable-downloads-with-air/) ** und ** [auch das] (http://mariusht.com/blog/2010/03/10/resumable -file-downloader-simple-air-app /) ** ... –

+0

Den Download fortzusetzen scheint mir gut zu sein. Wenn das vollständige Ereignis ausgelöst wird, bevor die Datei heruntergeladen wurde, kann ich versuchen, den Download mehrmals fortzusetzen und dann zu beenden, wenn es zu lange fehlschlägt. Ich würde mich freuen, wenn jemand das in einer Antwort angeben könnte. –

+1

Haben Sie eine 'int'-Variable, die die erwartete Dateigröße speichert. Wenn die Ereignisbeendigung jetzt ausgelöst wird, überprüfen Sie, ob Ihre [download]' fileData.length' gleich 'expected_FileSize' ist. Wenn weniger, versuchen Sie es erneut, bis das Ergebnis gleich oder gut genug ist. Um die letzte Byteanzahl zu erhalten, verwenden Sie eine "Reichweitenanforderung" im Anforderungsheader. Es wird auch gezeigt ** [in diesem Link] (https://suzhiyam.wordpress.com/tag/range-header-in-as3/) ** Wenn das Ihnen hilft. Etwas wie 'URLRequestHeader (" range "," bytes = "+ startPOS +" - "+ endPOS);' wobei startPOS "filedata.length + 1" und endPos "expected_FileSize" ist. –

Antwort

1

eine int-Variable Versuchen Sie, dass Geschäfte Dateigröße erwartet ..

wenn das Ereignis die komplette Brände jetzt überprüfen, ob Ihr [Download] fileData.length gleich expected_FileSize ist.

Wenn weniger als dann versuchen, bis gleich oder was auch immer ist gut genug. Um die letzte Byteanzahl zu erhalten, verwenden Sie eine "Reichweitenanforderung" im Anforderungsheader. Es wird auch in diesem Link angezeigt, wenn das Ihnen hilft.

So etwas wie URLRequestHeader("range","bytes="+startPOS+"-"+endPOS); wobei startPOS archivedata.length + 1 und endPos ist expected_FileSize Menge.

Verwandte Themen