나는 사무실 밖에서 많은 수의 디스플레이에 사용되는 RSS 티커를 만들고있다. 이 RSS 티커는 Twiter 피드 리더, 날씨 위젯 및 시계와 함께 모두 동일한 .fla로 실행됩니다.UrlLoader를 사용할 때 임시 네트워크 문제를 어떻게 관리합니까?
이러한 디스플레이가 많기 때문에 각자 온라인, rss, twitter 및 weather 데이터를 얻는 것을 원하지 않습니다. 이 모든 데이터는 인터넷에서 다운로드되는 여러 가지 간단한 XML 파일에 포함되어 있습니다.
Google 서버에서 실행되는 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;
}
이 접근 방법에 대해 더 잘 알고있는 사람이 있습니까? 여러분 모두가 제공 할 수있는 도움을 주시면 감사하겠습니다. 감사!
EDIT !!!
Will이 제안한대로 타이머 기반 네트워크 모니터링 하위 시스템을 만들려고했습니다. 내 RSS Ticker의 IO_ERROR 처리기에서 RSS 타이머를 중지하고 Network Monitoring Timer를 시작합니다. 10 초마다 서버에서 파일을 다운로드하려고 시도합니다. 그것은 작동 할 때까지 그렇게 계속되며, 타이머가 꺼지면 RSS 타이머가 다시 시작됩니다.
이론적으로 작동해야합니다. 뿐만 아니라 네트워크 파일 대신 웹 사이트를 다운로드하도록 변경하면 작동합니다. 네트워크 파일을 사용할 때 실패하면 연결이 다시 설정된 후에도 계속 실패합니다. 여기 내 코드입니다 : 내가 말했듯이 내가 http://www.google.ca에 "//server/shar/file.xml"을 전환하는 경우,
...
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();
}
, 그것을 작동합니다. 이더넷 연결을 끊으면 네트워크 모니터가 시작되어 다시 연결하면 RSS로 다시 전환되지만 ... 네트워크 리소스로 인해 계속 실패합니다 ...
networkMonitorXMLLoaderErrorHandler에 중단 점을 넣고 작동이 예상되면 변수 패널에서 이벤트의 속성을 확인하십시오. 로컬 대신 인터넷 URI를 사용할 때 일종의 보안 오류가 발생하는 것 같습니다. 하나. – shaunhusain