Давненько я не писал сюда ничего. На днях решил попробовать писать на AS3 (Action Script 3) в среде Adobe Flash CS3 с использованием "ВКонтакте API". Помучавшись с запросами к api.vkontakte.ru нашёл классы, призванные облегчить нам общение с ВКонтактом: vkontakte-as3
Всё бы хорошо, если не ограничение на 3 запроса в секунду . . . Классы, кстати вовсе не учитывают этого ограничения и лупят все запросы подряд. Написал простенький класс для распределения запросов по времени:
import flash.utils.*;
package main
{
import ru.vkontakte.VKApp;
public class TimeMgr
{
public var vk:VKApp = null;
private var isWaiting:Boolean = false;
private var prePreLastTime:Number = 0; // PrePreLast query time
private var preLastTime:Number = 0; // PreLast query time
private var lastTime:Number = 0; // Last query time
private var arr:Array = new Array();
private var realFunc:Function = null;
public function TimeMgr(vk_:VKApp) {
vk = vk_;
}
public function addQuery( ... args):void
{
arr.push(args);
if (isWaiting == false) {
isWaiting = true;
sendQuery(arr[0]);
}
}
private function justReleased(res:XML)
{
// Если ошибка
if ((res.name() != 'response') &&
(res.toString().indexOf('Too many') == 0))
{
setTimeout(sendQuery, 1000, arr[0]);
return;
}
// Отправка по месту назначения
if (realFunc != null)
setTimeout(realFunc, 0, res);
// Отправка следущего запроса из очереди
arr.shift();
if (arr.length > 0)
sendQuery(arr[0]);
else
isWaiting = false;
}
private function sendQuery(arg:Array)
{
// Куда передать ответ
if (arg[0] == vk.getVariable)
realFunc = arg[2];
else if (arg[0] == vk.putVariable)
realFunc = arg[3];
var t:Number = (new Date()).time;
if (t - prePreLastTime >= 1500) {
if (arg[0] == vk.getVariable)
vk.getVariable(arg[1], justReleased);
else if (arg[0] == vk.putVariable)
vk.putVariable(arg[1], arg[2], justReleased);
} else {
if (arg[0] == vk.getVariable)
setTimeout( arg[0], 1500 - (t - prePreLastTime),
arg[1], justReleased);
else if (arg[0] == vk.putVariable)
setTimeout( arg[0], 1500 - (t - prePreLastTime),
arg[1], arg[2], justReleased);
}
prePreLastTime = preLastTime;
preLastTime = lastTime;
lastTime = t;
}
}
}
* This source code was highlighted with Source Code Highlighter.
Теперь пишем код так:
// Не забудьте инициализацию vk:VKApp
var timer:TimeMgr = new TimeMgr(vk);
// Функция вызываемая при получении ответа севера
function vFunc(res:XML):void {
trace(res.name() + ':' + res.toString());
}
// <span style="font-style:italic;">Было раньше:</span>
// vk.putVariable(50, 'Test data', null);
// vk.getVariable(50, vFunc);
// <span style="font-style:italic;">Стало теперь:</span>
timer.addQuery(vk.putVariable, 50, 'Test data', null);
timer.addQuery(vk.getVariable, 50, vFunc);
* This source code was highlighted with Source Code Highlighter.
Запросов можно делать теперь сколько угодно, менеджер сам распределит их по времени. А вообще считаю это ограничение слишком уж строгим, ну хоть 10 в секунду было бы уже нормально. Можно было бы делать достаточно динамичные игры. Например, сетевой змейке - 3 запроса в секунду явно перекрыли кислород . . .
Полезные ссылки:
1. Повышение производительности AS3 приложений
2. Bitwise gems - fast integer math
Читать дальше