2010-02-03 65 views
20

我在寫一個簡單的REST服務,它響應來自客戶端的請求。全部用PHP。發送POST請求而不等待響應?

我擔心的是,當我的服務器響應請求時,如果客戶端發送回「ok」響應速度太慢,它最終可能會佔用資源。

如何通過lib_curl發送POST請求,將其設置爲不等待任何響應,而是在發送POST數據後馬上退出?

這甚至可能嗎?謝謝 !

+1

這不是發送200 OK響應的客戶端,而是服務器。 客戶端發出請求,服務器響應,服務器不關心客戶端正在發生什麼(按照REST的定義,它是無狀態的)。你在想什麼,你能否詳細說明一下? – meouw 2010-02-03 09:28:08

回答

13

你不能只發送數據,而不會收到答案與HTTP。 HTTP總是發出請求 - >響應。即使答案很短(就像一個沒有文字的簡單的200),也需要做出迴應。每個HTTP套接字都會等待這個響應。

如果你不關心響應,你可以添加一個進程到服務器,使你的請求,你只是你的請求數據給它(像在後臺運行的服務,檢查請求數據庫,並且每當添加新條目時始終開始請求)。這樣,您可以異步地發出請求,並在您將請求添加到堆棧後立即退出。

此外,正如ouw所說,客戶端不是你使用php進行的任何通信的一部分。 Php是一種服務器端語言,所以當客戶端請求一個網頁(php文件)時,服務器執行該文件(並執行所有請求php文件狀態),然後將結果返回給客戶端。

+0

這就是我需要知道的:)謝謝 – Gotys 2010-02-03 09:53:54

+0

@Gotys旁註,如果你想發送一個「請求」而不等待迴應,請查看UDP協議 – chris 2016-07-01 22:28:21

+0

有火和忘記「模式」。一個asyc請求會觸發請求。一旦執行,你可以做其他事情而無需等待。在你有一個可靠的網絡連接的情況下,UDP是一個選項,但TCP更可靠,因爲你知道這些數據包會生成它。但是,如果不檢查回覆,您將不知道發生了什麼。 – 2017-10-13 20:02:08

1

我從來沒有嘗試過這個,但將CURLOPT_TIMEOUT設置爲非常低的值可能會訣竅。嘗試00.1

但是,我不知道cURL和客戶端如何處理這個問題,當連接已經建立時連接是否會被主動取消,並且達到了超時。你將不得不嘗試。如果你打電話給PHP腳本,也許ignore_user_abort()可以確保你的腳本以任何一種方式運行。

+2

curl 0 timeout將讓它運行更長時間 – Boy 2016-11-02 02:43:48

+0

如果您要嘗試一個較低的超時,請使用毫秒變化curl_setopt($ curl,CURLOPT_TIMEOUT_MS,1); – 2017-10-17 19:57:27

12

這裏:

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); 
+1

你能提供解釋爲什麼這個工作 – 2016-10-06 10:36:14

+1

我發現了幾個解決方案,其中包括輸出緩衝區的一部分,但它仍然沒有爲我工作,直到我添加了這些捲曲選項。謝謝! – 2017-10-25 21:55:56

3

如果你真的不關心你可能最好關閉exec -ing一個wget命令的響應。這是在傳遞一些其他的答案中提到,但這裏有一個超級簡單的功能通過這種方式發送_POST包(這是異步的,需要1-2MS):

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/