Symfony: вызов ajax заставляет сервер ставить в очередь следующие запросы
У меня проблема с моим приложением, когда ajax-вызов на сервере занимает слишком много времени: он ставит все остальные запросы от пользователя в очередь, пока он не будет выполнен на стороне сервера (я понял, что отмена клиентской стороны вызова не имеет никакого эффекта, а пользователь все еще должен подождать).
Вот мой тестовый пример:
<script type="text/javascript" src="jquery-1.4.1.min.js"></script>
<a href="another-page.php">Go to another page on the same server</a>
<script type="text/javascript">
url = 'http://localserver/some-very-long-complex-query';
$.get(url);
</script>
Поэтому, когда запускается get, а затем после того, как я нажимаю на ссылку, сервер завершает обслуживание первого вызова, прежде чем перенести меня на другую страницу. Моя проблема в том, что я хочу избежать такого поведения.
Я нахожусь на сервере LAMP и ищу способ сообщить серверу, что пользователь прервал запрос с помощью функции, такой как connection_aborted(), как вы думаете, это путь? Кроме того, я знаю, что самая длинная часть этого сценария PHP - это запрос MySQL, поэтому, даже если я знаю, что connection_aborted () может обнаружить, что пользователь отменил вызов, мне все равно нужно проверить это во время запроса MySQL... I' Я не совсем уверен, что PHP может обрабатывать такого рода "события".
Так что, если у вас есть идея получше, я не могу дождаться, чтобы ее услышать.
Спасибо.
Обновление: после дальнейших исследований я обнаружил, что проблема возникает только с фреймворком Symfony (что я опускал до точного, мой плохой). Кажется, что вызов Ajax блокирует любой другой будущий вызов. Это может быть связано с контроллером или системой маршрутизации, я смотрю на это.
Также для тех, кто заинтересован в проблеме, вот мой новый контрольный пример: -новый проект с Symfony 1.4.3, конфигурация по умолчанию, я только что создал приложение и модуль по умолчанию. -jquery 1.4 для AJAX-запроса.
Вот мой actions.class.php (в моем уникальном модуле):
class defaultActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
//Do nothing
}
public function executeNewpage()
{
//Do also nothing
}
public function executeWaitingaction(){
// Wait
sleep(30);
return false;
}
}
Вот мой файл шаблона indexSuccess.php:
<script type="text/javascript" src="jquery-1.4.1.min.js"></script>
<a href="<?php echo url_for('default/newpage');?>">Go to another symfony action</a>
<script type="text/javascript">
url = '<?php echo url_for('default/waitingaction');?>';
$.get(url);
</script>
Для нового шаблона страницы это не очень актуально... Но с этим я могу воспроизвести проблему с блокировкой, которая есть в моем реальном приложении.
У кого-то еще есть такая же проблема?
Благодарю.
3 ответа
Хорошо, я наконец понял, почему приложение ожидает: сессионная система PHP ставит в очередь другой запрос, пока сессия не будет закрыта. Так что моему вызову ajax не нужно использовать сессию, я делаю $this->getUser()->shutdown(), прежде чем мое действие займет слишком много времени.
Все подробности здесь: http://garethmccumskey.blogspot.com/2009/10/php-session-write-locking-and-how-to.html
Нужно ли прервать его на сервере, или вы просто хотите, чтобы пользователь был перенаправлен немедленно?
Возможно, что-то вроде AJAXQueue подойдет вам? (с очевидными необходимыми изменениями в вашем коде на стороне клиента..)
Здравствуйте, у меня та же проблема, с похожим скриптом.
JQuery скрипт
$.ajax({url :'/map/test1', async:true ,complete: function(){alert("test1")}});
$.ajax({url :'/map/test2', async:true ,complete: function(){alert("test2")}});
Symfony php
public function executeTest1()
{
$this->getUser()->shutdown();
usleep(10000000);
return $this->renderText("Oki");
}
public function executeTest2()
{
return $this->renderText("Oki");
}
Когда страница загружается, test1 Requete ожидает окончания сна (10000000), но test2 ожидает окончания выполнения test1.
Я оправдал эту проблему с Symfony.