2012-08-30 68 views
1

我創建一個RSS北京時間要在一堆顯示器thoughout辦公室使用。此RSS Ticker將與Twiter Feed閱讀器,天氣小部件和時鐘一起運行,都在相同的.fla中。如何在使用UrlLoader時管理臨時網絡問題?

因爲有一噸的這些顯示器的,我不希望每一個到網上去的RSS,Twitter和天氣數據。所有這些數據都包含在從互聯網上下載的許多簡單的XML文件中。

我已經創建了我們的服務器上運行的Windows服務。該服務可以完成所有工作,只要觀看更新,並將新數據文件下載到我們網絡上的共享中即可。然後,我在所有顯示器上都有閃光燈儀表板從網絡副本中獲取他們的信息。這樣數據就會下載一次,而其他所有內容只是訪問這個本地緩存。

一切正常,但隨機的RSS股票將停止工作。我沒有任何辦法來遠程到這些顯示器,以檢查他們的錯誤日誌,但我得到我的本地測試環境完全相同的問題,當我拔掉我的以太網電纜。儀表板嘗試訪問網絡RSS副本,失敗,然後即使在重新建立連接後仍然會以計時器的每個滴答滴答失敗。

我希望能夠優雅地等待了一個斷開,那麼一旦重新連接顯示重新啓動RSS股票。我不知道如何做到這一點。下面是我的RSS相關的代碼:

// used to load a local xml file (stored in the same folder as the dashboard) that tells 
// the dashboards which RSS feeds can be found on the network, and where they are located. 
// It also contains the limits for how long each feed should be shown (both a time limit, 
// and a maximimum number of feed items) 

var rssListXMLLoader:URLLoader = new URLLoader(); 
rssListXMLLoader.addEventListener(Event.COMPLETE, rssListXMLLoaded); 
rssListXMLLoader.addEventListener(IOErrorEvent.IO_ERROR, ioRSSListXMLLoaderErrorHandler); 


// used to load the individual RRS feeds 

var rssFeedXMLLoader:URLLoader = new URLLoader(); 
rssFeedXMLLoader.addEventListener(Event.COMPLETE, rssFeedXMLLoaded); 
rssFeedXMLLoader.addEventListener(IOErrorEvent.IO_ERROR, ioRSSFeedXMLLoaderErrorHandler); 


// rssListXMLData:XML and rssFeedXMLData:XML are used to store the XML data that is returned 
// by the above loaders. 

var rssListXMLData:XML = new XML(); 
var rssFeedXMLData:XML = new XML(); 

var currentRSSIndex:int = 2^10; 
var currentFeedIndex:int = 2^10; 
var currentLimit_Feeds:int = 2^10; 
var currentLimit_Minutes:int = 2^10; 
var limitStartTime:Number = new Date().time; 
var gettingNewFeed = false; 

// the blow Timer is used to keep the ticker moving. Each tick, it checks to see of the 
// current RSS on sceen is has any text left. If it does, it removes the first letter 
// causing the string to appear as if it is scrolling from right to left. If it has no 
// more text, it gets the next feed. 

var rssTickerTMR:Timer = new Timer(100, 0); 
rssTickerTMR.addEventListener(TimerEvent.TIMER, updateRSSTicker); 
rssTickerTMR.start(); 

updateRSSTicker(); 

function updateRSSTicker(e:Event = null):void 
{ 
    if(ins_rssContent.text.length == 0) 
    { 
     if(!gettingNewFeed) 
     { 
      gettingNewFeed = true; 
      getNewFeed(); 
     } 
    } 
    else 
    { 
     ins_rssContent.text = ins_rssContent.text.substring(1); 
    } 
} 


// the below function checks to see if the RSS List is loaded. If it isn't it loads it, 
// if it is already loaded, it calls the rssListXMLLoaded. This way, rssListXMLLoaded is 
// never called unless the RSS List is already loaded. 

function getNewFeed():void 
{ 
    if (rssListXMLData == "") 
    { 
     trace("Loading RSS List XML"); 
     rssListXMLLoader.load(new URLRequest("rssFeeds.xml")); 
    } 
    else 
    { 
     rssListXMLLoaded(); 
    } 
} 


// the below function manages which feed needs to be used from the list. 

function rssListXMLLoaded(e:Event = null):void 
{ 
    if (e != null) 
    { 
     rssListXMLData = new XML(e.target.data); 
    } 

    currentFeedIndex++; 

    if (
      currentFeedIndex >= rssFeedXMLData.channel["item"].length() || 
      currentFeedIndex >= currentLimit_Feeds || 
      new Date().time - limitStartTime >= (currentLimit_Minutes * 1000 * 60) 
    ) 
    { 
     limitStartTime = new Date().time; 
     currentFeedIndex = 0; 
     currentRSSIndex++;  
     currentRSSIndex = (currentRSSIndex >= rssListXML.children().length()) ? 0 : currentRSSIndex;   
     currentLimit_Feeds = Number(rssListXMLData.RSSFeed[currentRSSIndex][email protected]) 
     currentLimit_Minutes = Number(rssListXMLData.RSSFeed[currentRSSIndex][email protected]) 
    } 
    try 
    { 
     rssFeedXMLLoader.load(new URLRequest(rssListXMLData.RSSFeed[currentRSSIndex])); 
    } 
    catch(e:Error) 
    { 
     trace("whoops, try again"); 
    } 
} 


// the below function sets the text on the dashboard, and sets gettingNewfeed to false. This allows the 
// rssTickerTMR:Timer to start removing the first letter of the newly added feed, causing the text to "scroll" 

function rssFeedXMLLoaded(e:Event):void 
{ 
    rssFeedXMLData = new XML(e.target.data); 

    if (rssFeedXMLData.channel["item"].length() > 0) 
    { 
     var dateString:String = rssFeedXMLData.channel["item"][currentFeedIndex].pubDate; 
     var date:Date = new Date(Date.parse(dateString.replace(" Z",""))); 

     if (date.toString() != "Invalid Date") 
     { 
      dateString = " @ " + FormatDate(date) + " " + FormatTime(date); 
     } 
     else 
     { 
      dateString = " @ " + dateString; 
     } 

     ins_rssTitle.text = rssFeedXMLData.channel.title + dateString; 

     ins_rssContent.text = "                  " 
          + cleanDescription(rssFeedXMLData.channel["item"][currentFeedIndex].title) + " - " 
          + cleanDescription(rssFeedXMLData.channel["item"][currentFeedIndex].description); 

     gettingNewFeed = false; 
    } 
    else 
    { 
     ins_rssContent.text = ""; 
     gettingNewFeed = false; 
    } 
} 

// removes the things from the RSS content that I don't want. 

function cleanDescription(p_string:String):String 
{ 
    if (p_string == null) 
    { 
     return ''; 
    } 

    var str:String = p_string.replace(/<\/?[^>]+>/igm, ''); //remove html tags. 
    str = str.split("\r").join(". "); //replace line breaks with '. ' 
    str = str.replace("\t"," "); //replace tabs with a single space. 
    str = str.replace(/(?:\.\s){2,}/g,". "); //replace multiple '. ' with a single one. 
    str = str.replace(/((https?|ftp|gopher|telnet|file|notes|ms-help): 
          ((\/\/)|(\\\\))+[\w\d:#@%\/;$()~_?\+-=\\\.&]*)/igm, ' '); //replaces URL text with a single space 
    str = str.replace(/#[\w]{3,}/igm,' ') //replaces hash tags with a single space 
    str = str.replace(/\s{2,}/igm," "); //replace multiple spaces with a single space 

    return str; 
} 

function ioRSSListXMLLoaderErrorHandler(e:Event):void 
{ 
    trace("ioRSSListXMLLoaderErrorHandler:"); 
    trace(e.toString()); 

} 


// the idea below is that it sets the text to "" and sets gettingNewFeed to false, which should get the 
// rssTickerTMR:Timer to try to get a band new feed. Theoretically, it should try and fail over and again 
// until the network is once again accessible. This doesn't work at all. 

function ioRSSFeedXMLLoaderErrorHandler(e:Event):void 
{ 
    trace("ioRSSFeedXMLLoaderErrorHandler:"); 
    trace(e.toString()); 

    ins_rssContent.text = ""; 
    gettingNewFeed = false; 
} 

有誰知道一個更好的方式來處理這個?我將不勝感激任何你可能會提供的幫助。謝謝!

編輯!

至於建議的意志,我試圖創建一個基於定時器的網絡監控子系統。在我的RSS訂單處理器的IO_ERROR處理程序中,我停止了RSS計時器,並啓動網絡監視計時器。每10秒鐘,它會嘗試從服務器下載一個文件。它繼續這樣做直到它工作,此時它關閉自己的計時器,重新啓動RSS計時器。

在理論上應該工作。不僅如此,如果我將其更改爲下載網站而不是網絡文件,它確實可行。使用網絡文件時,一旦失敗,即使重新建立連接後,它仍會保持失敗。這裏是我的代碼:

... 

function ioRSSFeedXMLLoaderErrorHandler(e:Event):void 
{ 
    rssTickerTMR.stop(); 
    networkMonitorTMR.start(); 

    trace("ioRSSFeedXMLLoaderErrorHandler:"); 
    trace(e.toString()); 

    ins_rssTitle.text = "Waiting for connection..."; 
    ins_rssContent.text = ""; 


} 

// netowrk monitor 
var networkMonitorXMLLoader:URLLoader = new URLLoader(); 
networkMonitorXMLLoader.addEventListener(Event.COMPLETE, networkMonitorXMLLLoaded); 
networkMonitorXMLLoader.addEventListener(IOErrorEvent.IO_ERROR, networkMonitorXMLLoaderErrorHandler); 

var networkMonitorTMR:Timer = new Timer(10000,0); 
networkMonitorTMR.addEventListener(TimerEvent.TIMER, checkNetwork); 


function checkNetwork(e:Event = null):void 
{ 
    networkMonitorXMLLoader.load(new URLRequest("//server/share/file.xml")); 
} 

function networkMonitorXMLLoaderErrorHandler(e:Event = null) :void 
{ 
    trace("Still Off"); 
} 

function networkMonitorXMLLLoaded(e:Event = null) :void 
{ 
    trace("Back On"); 
    rssTickerTMR.start(); 
    networkMonitorTMR.stop(); 
} 

就像我說的,如果我轉「//server/shar/file.xml」到http://www.google.ca,它的工作原理。當我拔掉我的以太網,網絡監控器啓動時,當我插回,它切換回RSS ...但我的網絡資源,它只是仍然失敗......

+0

將斷點在你networkMonitorXMLLoaderErrorHandler,並檢查了在變量面板中的事件的屬性,當你希望它是工作,我的猜測是,您使用的是互聯網的URI,而不是本地的,當獲得某種安全故障一。 – shaunhusain

回答

2

通用的模式來處理這些類型的問題是引發一個超時方法,在連接重新建立之前不斷檢查連接。理想情況下,你會在後臺執行此操作,以便用戶不會注意到。在你的情況,如果連接失敗(IO_ERROR),設置一個計時器到重試下載xml文件規定的時間量之後的方法。如果失敗,請重新設置。與此同時,您可以從頭開始重新顯示當前項目,並在新Feed下載完成後更新它們。

+0

我已經實施了您的建議,並發現問題出在加載網絡文件。它可以很好地與互聯網下載。有關更多詳情,請參閱我編輯的anser。感謝您的幫助! – Chronicide