Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отдать ответ и продолжить выполнение 
V
    Опции темы
solenko
Дата 11.8.2008, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 34
Всего: 67



Здравствуйте.
Есть ли возможность отдать ответ клиенту и после этого продолжить выполнение скрипта?
У меня просто довольно таки длительная обработка данных, и хочется после валидации сделать ответ типа:
"все ок, данные получил, начал обрабатывать"
и уже потом проводить обработку.


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Letov
Дата 11.8.2008, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 321
Регистрация: 22.2.2007
Где: Санкт-Петербург

Репутация: нет
Всего: 4



Если я правильно понял, то можно.
Код

<?php
//Прием данных
echo "<html><head><title>Some title</title></hrad><body>все ок, данные получил, начал обрабатывать</body></html>";
//Обработка данных
?>



--------------------
Не бывает плохих языков программирования. Бывают плохие программисты...

PM MAIL   Вверх
Anarki
Дата 11.8.2008, 08:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 14.3.2005

Репутация: 7
Всего: 11



Можно, скинуть буффер, у клиента появятся данные "все ок, данные получил, начал обрабатывать", а дальше браузер будет ждать пока скрипт не закончит работу.
Чтобы скинуть буфер, то есть вывести в браузер данные немедленно используется связка flush() + ob_flush()
Но есть несколько проблем, которые не дадут браузеру сразу отобразить информацию:
  • Особенности рендеринга браузера, браузер может ждать большой кусок данных и не выводить их пока столько данных столько не накопится, либо не будет закрыт какой-то элемент HTML
  • Всякие прокси серверы, которые являются мостиком между клиентом и сервером, они могут отдавать сразу целую страницу(то есть у клиента будет белый лист и загрузка, пока скрипт не отработает)
  • У веб сервера может быть включено например сжатие, и кусками страницу он не может отдать.
  • etc

Код

<?php
echo str_pad('',1024);
@ob_flush();
flush();

ob_flush нужен если выходной буфер перехватывается в php(есть обработчик ob_start())



--------------------
PM WWW   Вверх
solenko
Дата 11.8.2008, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 34
Всего: 67



Есть еще одна, самая главная проблема -- AJAX запросы.
redystate не будет установлен в 4 после сброса буфера. Да и браузер будет показывать, что страница еще не загрузилась. Т.е. нужно чтобы клиент понял, что передача данных закончена. 


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
piflit
Дата 11.8.2008, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 2.9.2007

Репутация: нет
Всего: нет



как вариант, отдавать оставшиеся данные на обработку другому скрипту
PM MAIL   Вверх
solenko
Дата 11.8.2008, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 34
Всего: 67



piflit, вариант не очень, т.к. это ровно в 2 раза увеличить нагрузку + запросы по http к самому себе (через cli не получится). 


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Feldmarschall
Дата 11.8.2008, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 22
Всего: 32



Цитата(solenko @  11.8.2008,  10:09 Найти цитируемый пост)
Есть еще одна, самая главная проблема

ну так, может быть, не стравливать проблемы по одной, а взять, и написать толком всю задачу?
в описанной постановке никакой проблемы вообще не видно. 
если есть аякс, то непонятно, зачем что-то выводить скриптом, когда можно аяксом?
если говорить о самом первом вопросе, то почему не сделать, как во всех этих кривых вбуллетинах: "процесс поиска запущен, скоро вы будете перенаправлены на результат", примитивным мета-рефрешем?
PM   Вверх
solenko
Дата 11.8.2008, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 34
Всего: 67



Ок. Задача полностью. Из facebook приложения делается ajax запрос на мой сервак. Т.е. запрос проходит по пути:
клиент -> facebook -> мой сервер
пришедшие данные нужно первоначально обработать и выдать ответ (на входе координаты, на выходе адрес). Работать в обход facebook нельзя, т.к. ответ должен содержать fbml, который интерпретируетя их сервером, т.е. нужно действительно завершить передачу данных. Кроме самого геокодинга нужно выполнить еще несколько дейтсвий, о результатах которых пользователя информировать уже не нужно. Почти все эти действия -- REST запросы, т.е. процесс довольно таки длительный.
Нужно -- сократить время отклика сервера. Самый оптимальный путь, который я вижу -- отдать ответ до выполнения REST запросов.

Это сообщение отредактировал(а) solenko - 11.8.2008, 22:24


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Feldmarschall
Дата 12.8.2008, 06:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок
****


Профиль
Группа: Участник
Сообщений: 2641
Регистрация: 11.12.2007

Репутация: 22
Всего: 32



речь, как я понимаю, о закрытии сокета?
в этом случае, если не ошибаюсь, единственный способ - это форкать скрипт, как предлагал piflit 
ну, и определиться, какую задачу решаем - сокращаем время отклика или нагрузку. не пытаясь решить сразу обе.
только непонятно, почему по http-то себе запросы. и как оно по http поможет? курл, что ли? а как это сократит время работы вызывающего скрипта?
единственный способ, который я знаю - это вызов консольной команды через system с переводом её в фон. если это невозможно, то предлагаю подумать над реализацией этой возможности

PM   Вверх
sTa1kEr
Дата 12.8.2008, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



solenko, существует несколько способов.
Первый, имхо, самый правильный - это сказать клиенту, что бы закрывал коннект по получении ответа. 14.10 Connection
Цитата

 HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after completion of the response. For example,

       Connection: close

in either the request or the response header fields indicates that the connection SHOULD NOT be considered `persistent' (section 8.1) after the current request/response is complete. 

Но в этом случае нужно будет самому формировать заголовок Content-Length, т.к. сервер не знает когда скрипт перестанет передавать данные и, соответствено, не сожет его сформировать до окончания работы скрипта. Т.о. вручную сформировав и отправив эти заголовки, клиент закроет коннект после получения указанного размера контента, а сам скрипт при этом продолжит работу.

Второй вариант - это использовать Shutdown Handler. Зарегистрированная таким образом функция будет вызвана уже после того как сервер окончательно сформирует и отправит ответ клиенту.

Ну и последний вариант - это, как уже говорили, fork.

Это сообщение отредактировал(а) sTa1kEr - 12.8.2008, 11:19
PM MAIL   Вверх
solenko
Дата 14.8.2008, 09:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 34
Всего: 67



Попробовал вариант с Connection: Close. Что-то не получается. Тестовый исходник:
Код

<?php
$string = 'some data for test';
header("Connection: Close");
header("Content-Length: ".strlen($string));
header("Content-MD5: ".md5($string));
echo $string;
flush();
sleep(50);
$string = 'Another data';
file_put_contents('out', $string);
echo $string;

Что получаем в итоге:
Клиент ждет ответа 50 секунд, после чего выводит первую строку. Header'ы:
Connection: keep-alive

Нужна ли какая-то дополнительная конфигурация сервера чтобы использовать Connection: Close? Где я ошибся? 


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
sTa1kEr
Дата 14.8.2008, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Цитата(solenko @  14.8.2008,  10:31 Найти цитируемый пост)
Header'ы:
Connection: keep-alive

Это в response хидерах? Скорее всего вы используете какйо-либо reverse-proxy, к примеру nginx? Если да, то дело скорее всего в нем, решение проблемы - обращатся к серверу на прямую.
PM MAIL   Вверх
Anarki
Дата 14.8.2008, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 14.3.2005

Репутация: 7
Всего: 11



В Apache2 с включенной опцией KeepAlive On нормально отсылает Connection: Close


--------------------
PM WWW   Вверх
solenko
Дата 14.8.2008, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1473
Регистрация: 15.1.2006
Где: Украина

Репутация: 34
Всего: 67



Дома на Win Vista, Apache2.2 отправлялись keep-alive.
На работе Linux + Apache2.2 -- все отлчно.

Огромное спасибо за помощь -- это действительно то решение, которое я искал.


--------------------
Ла-ла-ла-ла
Заметьте, нет официального подтверждения, что это не просто четыре слога.
PM MAIL WWW ICQ Skype   Вверх
Mihalch
Дата 31.8.2014, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 31.8.2014

Репутация: нет
Всего: нет



Цитата(Anarki @ 11.8.2008,  08:53)
Код

<?php
echo str_pad('',1024);
@ob_flush();
flush();

Anarki, Спасибо!
Из всего, что удалось найти, только твой способ и работает.
Причём именно с echo str_pad('',1024), хотя бы 1 раз. Дальше уже и просто flush() выводит.
А сам по себе flush();, как везде советуют, не действует.
Находил ещё только один способ (там в самом низу) заставить flush() выводить текст с продолжением выполнения скрипта. Но там 30 строк кода и 2 цикла. А тут всё компактно.
Спасибо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1206 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.