簡體   English   中英

PHP Multi curl 帶不同端口

[英]PHP Multi curl with different ports

我正在使用 IOT 系統並嘗試改進我們的數據攝取。 目前,我們正在迭代一組具有不同端口的 URL,並一次發送一個 curl 請求。 我想使用 multicurl 來解決這個瓶頸,但我只得到錯誤作為響應。 這是我的代碼(IP 地址已編輯)

$url = 'http://XXX.XXX.XX.XXX/getvar.csv';
$ports = [8101,8102,8103,8104];

foreach ($ports as $port) {
        $worker = curl_init($curl_url);
        curl_setopt_array($worker, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_HEADER => 0,
            CURLOPT_TIMEOUT => 8,
            CURLOPT_POSTFIELDS => $content,
            CURLOPT_PORT => $port
        ]);

        curl_multi_add_handle($mh, $worker);
    }
$i=0;
for (; ;) {
    $still_running = null;
    echo "<p>exec multi curl $i</p>";
    do {
        echo "<p>curl multi exec</p>";
        $err = curl_multi_exec($mh, $still_running);
    } while ($err === CURLM_CALL_MULTI_PERFORM);
    if ($err !== CURLM_OK) {
        $description = curl_strerror(curl_errno($mh));
        echo "<p>Error description: $description</p>";
        // handle curl multi error?
    }
    if ($still_running < 1) {
        echo "<p>curl multi finished</p>";
        // all downloads completed
        break;
    }
    // some haven't finished downloading, sleep until more data arrives:
    curl_multi_select($mh, 8);
    $i++;
}

$curl_time_stop = microtime(true);
$curl_duration += $curl_time_stop - $curl_time_start;
echo "CURL finished";
$results = [];
while (false !== ($info = curl_multi_info_read($mh))) {
    if ($info["result"] !== CURLE_OK) {
        echo "Error ".curl_strerror($info["result"]);
        // handle download error?
    }
    $results[curl_getinfo($info["handle"], CURLINFO_EFFECTIVE_URL)] = 
    curl_multi_getcontent($info["handle"]);
    curl_multi_remove_handle($mh, $info["handle"]);
    curl_close($info["handle"]);
}
curl_multi_close($mh);
var_dump($results);

這是我得到的錯誤/響應

Error Server returned nothing (no headers, no data)
results int(1) int(52) resource(29) of type (curl)

據我所知,錯誤代碼 52 對應於CURLE_GOT_NOTHING 有什么我想念的嗎? 還是多卷曲與 curl 使用的協議有區別?

[編輯:添加詳細輸出] 這是我使用CURLOPT_VERBOSE=>1時的結果

*   Trying 1XX.XX.XX.XX:8101...

* Found bundle for host 1XX.XX.XX.XX: 0x2625a00 [serially]
* Server doesn't support multiplex (yet)
* Hostname 1XX.XX.XX.XX was found in DNS cache
*   Trying 1XX.XX.XX.XX:8101...

*** Connected to 1XX.XX.XX.XX (1XX.XX.XX.XX) port 8101 (#0)
> POST /getvar.csv? HTTP/1.1
Host: 1XX.XX.XX.XX:8101
Accept: */*
Content-Length: 248
Content-Type: application/x-www-form-urlencoded**

* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/csv; charset="utf-8"
< Server: embedded HTTPD
< Expires: 1 JAN 2013 00:00:00 GMT
< Last-Modified: 4 MAR 2021 12:10:09 GMT
< Cache-Control: no-cache
< Transfer-Encoding: chunked

* Connection #0 to host 1XX.XX.XX.XX left intact
* Empty reply from server
* Closing connection 25

我發現我的代碼存在外部問題,但我在此處發布最終的工作代碼以供將來參考。 Multi-curl 不喜歡迭代端口號,所以我不得不將端口烘焙到 curl URL 並迭代 URL 數組。 $content不是 multicurl 工作所必需的,但它是從我正在調用的 URL 中獲取數據。

<?php


$lists=[
    "LocalBoardTemp"
];
$url = 'http://XXX.XXX.XXX.XXX:';

$ports = [8101,8102,8103,8104,8105,8106,8107,8108,8109];

foreach ($ports as $port) {
    $curl_urls[] = $url.$port.'/getvar.csv?';
}
$content = '';
foreach ($lists as $list1) {
    $content = $content . "&name=" . $list1;
}

$mh = curl_multi_init();
$fp = fopen(dirname(__FILE__).'/curl_errorlog.txt', 'w');
$i=0;
foreach ($curl_urls as $url) {
    $worker = curl_init($url);
    curl_setopt_array($worker, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HEADER => 0,
        CURLOPT_TIMEOUT => 8,
        CURLOPT_POSTFIELDS => $content,
        CURLOPT_VERBOSE=>1,
        CURLOPT_STDERR => $fp
//        ,
//        CURLOPT_PORT => $port
    ]);
    curl_multi_add_handle($mh, $worker);
}
for (; ;) {
    $still_running = null;
    echo "<p>exec multi curl $i</p>";
    do {
        echo "<p>curl multi exec</p>";
        $err = curl_multi_exec($mh, $still_running);
    } while ($err === CURLM_CALL_MULTI_PERFORM);
    if ($err !== CURLM_OK) {
        $description = curl_strerror(curl_errno($mh));
        echo "<p>Error description: $description</p>";
        // handle curl multi error?
    }
    if ($still_running < 1) {
        echo "<p>curl multi finished</p>";
        // all downloads completed
        break;
    }
    // some haven't finished downloading, sleep until more data arrives:
    curl_multi_select($mh, 8);
    $i++;
}

echo "CURL finished";
$results = [];
$j = 0;
while (false !== ($info = curl_multi_info_read($mh))) {

    if ($info["result"] !== CURLE_OK) {
        echo "Error ".curl_strerror($info["result"]);
        // handle download error?
    }
    echo "<p>results ";
    foreach ($info as $x) {
        var_dump($x);
    }
    echo "</p>";
    $results[curl_getinfo($info["handle"], CURLINFO_EFFECTIVE_URL)] = curl_multi_getcontent($info["handle"]);
    echo "<p>result index $j". curl_multi_getcontent($info["handle"])."</p>";
    curl_multi_remove_handle($mh, $info["handle"]);
    curl_close($info["handle"]);
    $j++;
}
curl_multi_close($mh);
echo "<p>All results dump: ";
var_dump($results);
echo "</p>";
fclose($fp);
echo "finished";

這是由幾個教程和堆棧溢出答案拼湊而成的,所以我確信有一種更有效的方法可以做到這一點,但它確實有效。

暫無
暫無

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

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