簡體   English   中英

PHP CLI並行讀寫多個原始tcp API,例如curl_multi_init用於https API

[英]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_nonblocksocket_select

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM