PHP - отправка быстрого ответа API клиенту во время работы сервера - PullRequest
0 голосов
/ 07 августа 2010

Я создал API, который используется на нескольких сайтах.Клиентские сайты вызывают сервер с помощью file_get_contents или curl и получают доступ к нашему URL-адресу, например "http://www.myserver.com/api/record.php?some=thing".. Клиент выполняет вызов, а затем ожидает ответа API, прежде чем обрабатывать оставшуюся часть страницы. Однако некоторые изклиенту не требуется никаких выходных данных от API.

Мне интересно, есть ли способ для сервера вывести что-то, чтобы клиент не ждал этого, пока процесс сервера выполняет то, чточто-то вроде «страница готова», так что клиент больше не ждет, пока он загрузится, но серверный скрипт все еще работает в течение секунды, пока он вставляет записи в базу данных.

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

Есть предложения? Я знаю, что я выполняю вызов асинхронно с javascriptбудет работать, но мы обнаружили, что доступ к PHP должен быть более надежным, чем JS.

Спасибо, так многоч!

Ответы [ 3 ]

0 голосов
/ 07 августа 2010

edit : подумав еще раз, вы не получите никакой выгоды от асинхронного запроса.Просто сделайте обычный запрос с помощью fsockopen и убейте его после того, как fwrite закончил заголовки.

Вы можете просто сделать запрос HEAD, чтобы указать, что тело ответа не нужно - этосохранить несколько поездок.

В принципе, вы можете сделать асинхронный запрос .После того, как вы напишите заголовки, вы должны убедиться, что они были отправлены правильно.В этот момент вы можете прервать соединение и положиться на ignore_user_abort на стороне сервера.(Я не уверен, что это будет работать со всеми веб-серверами, хотя, возможно, возможно, что запрос никогда не достигнет PHP после столь раннего прерывания пользователя).

0 голосов
/ 07 августа 2010

Связь между вашим скриптом и вашим API - это сложная вещь; Вы должны прекратить его для возврата curl или file_get_contents. (вы можете посмотреть на асинхронные функции curl_multi_ * или выполнить свою собственную обработку сокетов, как предложено artefacto)

Один из вариантов - поместить обработку бэкэнда в фоновый процесс, например так:

$desc = array(); // fd descriptors
$proc = proc_open("/bin/sleep 60 &",$desc,$pipes);

где сон только для доказательства концепции. Он продолжает жить счастливо после того, как соединение установлено. Недостатком является то, что если у вас есть какой-либо подключенный fd, дочерний процесс умрет с родителем, поэтому вы должны передать данные через командную строку или $ env (5-й аргумент в proc_open)

0 голосов
/ 07 августа 2010

Вы можете сделать это так:

ob_start();

//create and output any output to be sent to the browser.

// get the size of the output
$size = ob_get_length();

// send headers to tell the browser to close the connection
header("Content-Length: $size");
header('Connection: close');

// flush all output
ob_end_flush();
ob_flush();
flush();

//do any post-processing here.
...