Я пишу простой сервис REST, который отвечает на запросы клиентов. Все в PHP.
Я беспокоюсь, что когда мой сервер отвечает на запрос, он может привести к связыванию ресурсов, если клиентская сторона слишком медленно отправляет ответ «ok».
Как отправить запрос POST через lib_curl, чтобы он не дождался каких-либо ответов, а скорее ушел с момента отправки данных POST?
Возможно ли это? Спасибо !
Вы не можете просто отправлять данные, не получая ответа с помощью HTTP. HTTP всегда отправляет запрос -> ответ. Даже если ответ очень короткий (как простой 200 без текста), должен быть ответ. И каждый HTTP-сокет будет ждать ответа.
Если вас не интересует ответ, вы можете добавить процесс на сервер, который делает ваши запросы, и вы просто нажимаете на него свои данные запроса (например, службу, работающую в фоновом режиме, проверку базы данных запросов и всегда начиная запрос при добавлении новой записи). Таким образом, вы сделаете запрос асинхронно и можете выйти, как только вы добавите этот запрос в стек .
Также, как сказал meuw, клиент не является частью какого-либо общения, которое вы делаете с php. Php – это серверный язык, поэтому, когда клиент запрашивает веб-страницу (файл php), сервер выполняет этот файл (и выполняет все запросы к файлу php), а затем возвращает результат клиенту.
Вот:
ob_end_clean(); header("Connection: close\r\n"); header("Content-Encoding: none\r\n"); header("Content-Length: 1"); ignore_user_abort(true);
и завиток:
curl_setopt($curl, CURLOPT_TIMEOUT_MS, 1); curl_setopt($curl, CURLOPT_NOSIGNAL, 1);
Если вы действительно не заботитесь об ответе, вы, вероятно, лучше всего выполняете команду wget. Это упоминается в некоторых других ответах, но вот супер простая функция для отправки пакета _POST
помощью этого подхода (который является асинхронным и занимает 1-2 мс):
function wget_request($url, $post_array, $check_ssl=true) { $cmd = "curl -X POST -H 'Content-Type: application/json'"; $cmd.= " -d '" . json_encode($post_array) . "' '" . $url . "'"; if (!$check_ssl){ $cmd.= "' --insecure"; // this can speed things up, though it's not secure } $cmd .= " > /dev/null 2>&1 &"; //just dismiss the response exec($cmd, $output, $exit); return $exit == 0; }
Кредиты: функция была адаптирована с https://segment.com/blog/how-to-make-async-requests-in-php/
http://curl.haxx.se/mail/lib-2002-05/0090.html
libcurl не имеет асинхронного интерфейса. Вы можете сделать это самостоятельно либо с помощью потоков, либо с помощью неблокирующего «мультиинтерфейса», предлагаемого libcurl. Ознакомьтесь с несколькими интерфейсами здесь:
http://curl.haxx.se/libcurl/c/libcurl-multi.html
PHP-пример мультиинтерфейса:
http://www.phpied.com/simultaneuos-http-requests-in-php-with-curl/
Я никогда не пробовал этого, но настройка CURLOPT_TIMEOUT
на очень низкое значение может сделать трюк. Попробуйте 0
или 0.1
.
Однако я не знаю, как cURL и клиент будут вести себя с этим, будет ли соединение активно отменено, когда соединение уже установлено, и тайм-аут будет достигнут. Тебе придется попробовать. Если вы вызываете PHP-скрипты, возможно, ignore_user_abort()
может убедиться, что ваши сценарии проходят в любом случае.
Как говорят другие люди, когда вы делаете HTTP-запрос, вам нужно ждать ответа.
В PHP вы можете сделать запрос с помощью функции exec.
Проверьте эту ссылку: команда php exec (или аналогичная), чтобы не дождаться результата