Длинный опрос в as3
Меня интересует длинный опрос - можно ли его реализовать через URLLoader в as3? У меня есть php-сервер, который периодически проверяет наличие обновлений и должен отправить их обратно клиенту. Я не хочу использовать сокеты (в недавнем проекте было множество проблем с антивирусами и брандмауэрами).
Итак, в основном:
- Клиент отправляет запрос post\get в php скрипт через URLLoader.
- php проверяет наличие обновлений, если есть какие-либо отправляет их обратно, если нет, спит в течение 500 мс, чем проверяет снова.
- Клиент получает обновление - и повторяет с шага 1.
Я предполагаю, что главный вопрос - URLLoader\ или URLRequest закроет это соединение по таймауту, и я могу как-то его настроить, чтобы ждать обновления, скажем, в течение 1 минуты?
1 ответ
Спасибо за все ваши комментарии. Я сделал тестовое приложение, чтобы проверить, может ли URLStream делать то, что я хочу, и это делает. Итак, код PHP:
<?php
header('Content-Type: application/json; charset=utf-8');
$sleepTime=1*1000000; //every second
$endTime=time()+60*1; //after one minute
while(time()<$endTime)
{
usleep($sleepTime);
pushRandom();
}
echo json_encode(array('time'=>time(), 'message'=>'Bye world!'));
flush();
ob_flush();
function pushRandom()
{
echo json_encode(array('time'=>time(), 'number'=> rand(1, 10000)));
flush();
ob_flush();
}
?>
Что это делает - повторяет объект JSON каждую секунду в течение минуты. После этого перекликается с Bye World и закончил опрос.
И код as3:
package com.drabuna.as3longpoll
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.utils.ByteArray;
public class LongPoll extends EventDispatcher
{
private var url:String;
private var urlRequest:URLRequest;
private var urlStream:URLStream;
private var bytesRead:int=0;
public function LongPoll(serverURL:String)
{
url=serverURL;
}
public function startPolling():void
{
urlRequest=new URLRequest(url);
urlStream=new URLStream();
urlStream.addEventListener(ProgressEvent.PROGRESS, onPollData);
urlStream.addEventListener(Event.COMPLETE, onPollFinished);
urlStream.addEventListener(IOErrorEvent.IO_ERROR, onPollError);
urlStream.load(urlRequest);
}
public function endPolling():void
{
if(urlStream.connected)
{
urlStream.close();
}
}
private function onPollData(e:ProgressEvent):void
{
if(urlStream.bytesAvailable>bytesRead)
{
var byteArray:ByteArray=new ByteArray();
urlStream.readBytes(byteArray, bytesRead, urlStream.bytesAvailable-bytesRead);
var tempString:String=byteArray.readUTFBytes(byteArray.bytesAvailable);
var error:Boolean=false;
try
{
var jsonObject:Object=JSON.parse(tempString);
}
catch(e:Error)
{
error=true;
}
if(!error)
{
bytesRead=urlStream.bytesAvailable;
var evt:LongPollEvent=new LongPollEvent(LongPollEvent.POLL_DATA);
evt.data=jsonObject;
this.dispatchEvent(evt);
}
}
}
private function onPollFinished(e:Event):void
{
var evt:LongPollEvent=new LongPollEvent(LongPollEvent.POLL_FINISHED);
this.dispatchEvent(evt);
}
private function onPollError(e:IOErrorEvent):void
{
var evt:LongPollEvent=new LongPollEvent(LongPollEvent.POLL_ERROR);
evt.data=e;
this.dispatchEvent(evt);
}
}
}
Простой класс, который читает поток и разбирает его на объекты as3. Все отлично работает!)