[英]PHP CLI writing and reading multiple raw tcp API's in parallel like curl_multi_init for https API's
我的情況:
我有多個運行原始TCP API的服務器,要求我發送一個字符串以從中獲取信息。 我需要在5秒鍾的超時時間內得到響應。 應該同時聯系所有API,然后從那里獲得5秒鍾的響應時間。 (因此,一次所有服務器的最大執行時間為5秒)
我已經設法通過PHP cURL對HTTP / S API做到了:
// array of curl handles
$multiCurl = array();
// data to be returned
$result = array();
// multi handle
$mh = curl_multi_init();
foreach ($row_apis as $api) {
$id = $api[0];
$ip = $api[1];
$port = $api[2];
// URL from which data will be fetched
$fetchURL = "$ip:$port/api/status";
$multiCurl[$id] = curl_init();
curl_setopt($multiCurl[$id], CURLOPT_URL,$fetchURL);
//curl_setopt($multiCurl[$id], CURLOPT_HEADER,0);
curl_setopt($multiCurl[$id], CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($multiCurl[$id], CURLOPT_CUSTOMREQUEST,"GET");
curl_setopt($multiCurl[$id], CURLOPT_TIMEOUT,5);
curl_setopt($multiCurl[$id], CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle($mh, $multiCurl[$id]);
}
$index=null;
do {
curl_multi_exec($mh,$index);
} while($index > 0);
// get content and remove handles
foreach($multiCurl as $k => $ch) {
$result[$k] = json_decode(curl_multi_getcontent($ch), true);
curl_multi_remove_handle($mh, $ch);
}
// close
curl_multi_close($mh);
此示例一次獲取所有API,並等待5秒鍾重新放置。 永遠不會超過5秒。
有沒有辦法用PHP中的原始TCP API做同樣的事情? 我已經嘗試使用套接字,並且能夠獲取信息,但是每個API都是一個接一個的獲取的,因此該腳本占用了多台服務器的時間。
謝謝你的幫助。
編輯:
我已經嘗試實現您的建議,現在我的代碼如下所示:
$apis = array();
$apis[0] = array(1, "123.123.123.123", 1880);
$method = "summary";
$sockets = array();
//Create socket array
foreach($apis as $api){
$id = $api[0];
$ip = $api[1];
$port = $api[2];
$sockets[$id] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sockets[$id]);
@socket_connect($sockets[$id], $ip, $port);
//socket_write($sockets[$id], $method);
}
//Write to every socket
/*
foreach($sockets as $socket){
socket_write($socket, $method);
//fwrite($socket, "$method");
}
*/
//Read all sockets for 5 seconds
$write = NULL;
$except = NULL;
$responses = socket_select($sockets, $write, $except, 5);
//Check result
if($responses === false){
echo "Did not work";
}
elseif($responses > 0){
echo "At least one has responded";
}
//Access the data
//???
但是,由於socket_select的結果是0,何時需要將方法寫入套接字? 如果我能得到一些回饋,該如何訪問響應中的數據?
絕對。 將SO_SNDBUF
設置為適當的大小,以便您可以立即/非阻塞地發送所有請求,然后發送所有請求,然后開始等待/讀取響應。
讀取的簡單方法是在套接字上調用socket_set_block
,並按1讀取所有響應,但這並不能保證5秒鍾的超時(但是同樣,您的示例curl_multi代碼也沒有),如果您需要5秒鍾的超時時間,請改用socket_set_nonblock
& socket_select
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.