我可以针对同一个URL执行多个并行cURL吗?

时间:2013-12-10 10:30:57

标签: php soap curl parallel-processing

我需要使用cURL并行执行多个请求,但我需要针对相同的URL执行此操作。

这是因为是一个SOAP Web服务,我有一个唯一的URL,但我会发送不同的标题来接收我需要的多个响应。

我尝试制作一个curl_multi_exec,但我var_dump $ channels数组并且我只收到1,我认为是因为cURL重新使用连接,所以我尝试了CURLOPT_FRESH_CONNECT和CURLOPT_FORBID_REUSE而没有成功。

知道如何实现它吗?

    $url = "http://myURL.com/SOAPWebservice.svc";
    $stationIds = array(207,303,305,195,204,205);//5,10);
    // 207,303,305,195,204,205,206,212,306,196,193,194,307,312,197,198,199,200,201,202,203,302,308,367,304,309,310,311

    $multi = curl_multi_init();
    $channels = array();

    // Loop through the URLs, create curl-handles
    // and attach the handles to our multi-request
    foreach ($stationIds as $stationId)
    {
        $soap_request =
            '<?xml version="1.0" encoding="UTF-8"?>
                <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns6930="http://tempuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                    <SOAP-ENV:Body>
                        <GetStationById xmlns="http://tempuri.org/">
                            <StationID>' . $stationId . '</StationID>
                            <CityID>5</CityID>
                        </GetStationById>
                    </SOAP-ENV:Body>
                </SOAP-ENV:Envelope>';

        $header = array(
            "Content-type: text/xml;charset=\"utf-8\"",
            "Accept: text/xml",
            "Cache-Control: no-cache",
            "Pragma: no-cache",
            "SOAPAction: \"http://tempuri.org/IBLLStation/GetStationById\"",
            "Content-length: ".strlen($soap_request),
        );


        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,            $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt($ch, CURLOPT_POST,           true );
        curl_setopt($ch, CURLOPT_POSTFIELDS,     $soap_request);
        curl_setopt($ch, CURLOPT_HTTPHEADER,     $header);
        curl_setopt($ch, CURLOPT_FRESH_CONNECT,     TRUE);
        curl_setopt($ch, CURLOPT_FORBID_REUSE,     TRUE);

        curl_multi_add_handle($multi, $ch);

        $channels[$url] = $ch;
    }

    // While we're still active, execute curl
    $active = null;
    do {
        $mrc = curl_multi_exec($multi, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active && $mrc == CURLM_OK) {
        // Wait for activity on any curl-connection
        if (curl_multi_select($multi) == -1) {
            continue;
        }

        // Continue to exec until curl is ready to
        // give us more data
        do {
            $mrc = curl_multi_exec($multi, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }

    // Loop through the channels and retrieve the received
    // content, then remove the handle from the multi-handle
    $StationsLastContact = "";
    // echo print_r($channels,TRUE);
    foreach ($channels as $channel) {
        $response = curl_multi_getcontent($channel);
        $startsAt           = strpos($response, "StationLastContact>") + strlen("StationLastContact>");
        $endsAt             = strpos($response, "<", $startsAt);
        $StationLastContact = substr($response, $startsAt, $endsAt - $startsAt);
        $StationLastContact .= "<br />";
        $StationsLastContact .= $StationLastContact;
        curl_multi_remove_handle($multi, $channel);
    }

    // Close the multi-handle and return our results
    curl_multi_close($multi);

    die($StationsLastContact);

1 个答案:

答案 0 :(得分:1)

检查以下代码是否有效。我只使用了一个处理程序数组。

var_dump($ch);

array(6) {
  [207]=>
  resource(3) of type (curl)
  [303]=>
  resource(4) of type (curl)
  [305]=>
  resource(5) of type (curl)
  [195]=>
  resource(6) of type (curl)
  [204]=>
  resource(7) of type (curl)
  [205]=>
  resource(8) of type (curl)
}


    $url = "http://myURL.com/SOAPWebservice.svc";
    $stationIds = array(207,303,305,195,204,205);//5,10);
    // 207,303,305,195,204,205,206,212,306,196,193,194,307,312,197,198,199,200,201,202,203,302,308,367,304,309,310,311

    $multi = curl_multi_init();
    $channels = array();

    // Loop through the URLs, create curl-handles
    // and attach the handles to our multi-request
    foreach ($stationIds as $stationId)
    {
        $soap_request =
            '<?xml version="1.0" encoding="UTF-8"?>
                <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns6930="http://tempuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                    <SOAP-ENV:Body>
                        <GetStationById xmlns="http://tempuri.org/">
                            <StationID>' . $stationId . '</StationID>
                            <CityID>5</CityID>
                        </GetStationById>
                    </SOAP-ENV:Body>
                </SOAP-ENV:Envelope>';

        $header = array(
            "Content-type: text/xml;charset=\"utf-8\"",
            "Accept: text/xml",
            "Cache-Control: no-cache",
            "Pragma: no-cache",
            "SOAPAction: \"http://tempuri.org/IBLLStation/GetStationById\"",
            "Content-length: ".strlen($soap_request),
        );


        $ch[$stationId] = curl_init();
        curl_setopt($ch[$stationId], CURLOPT_URL,            $url);
        curl_setopt($ch[$stationId], CURLOPT_RETURNTRANSFER, true );
        curl_setopt($ch[$stationId], CURLOPT_POST,           true );
        curl_setopt($ch[$stationId], CURLOPT_POSTFIELDS,     $soap_request);
        curl_setopt($ch[$stationId], CURLOPT_HTTPHEADER,     $header);
        curl_setopt($ch[$stationId], CURLOPT_FRESH_CONNECT,     TRUE);
        curl_setopt($ch[$stationId], CURLOPT_FORBID_REUSE,     TRUE);

        curl_multi_add_handle($multi, $ch[$stationId]);
    }

    // While we're still active, execute curl
    $active = null;
    do {
        $mrc = curl_multi_exec($multi, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);

    while ($active && $mrc == CURLM_OK) {
        // Wait for activity on any curl-connection
        if (curl_multi_select($multi) == -1) {
            continue;
        }

        // Continue to exec until curl is ready to
        // give us more data
        do {
            $mrc = curl_multi_exec($multi, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }

    // Loop through the channels and retrieve the received
    // content, then remove the handle from the multi-handle
    $StationsLastContact = "";
    // echo print_r($channels,TRUE);
    foreach ($ch as $channel) {
        $response = curl_multi_getcontent($channel);
        $startsAt           = strpos($response, "StationLastContact>") + strlen("StationLastContact>");
        $endsAt             = strpos($response, "<", $startsAt);
        $StationLastContact = substr($response, $startsAt, $endsAt - $startsAt);
        $StationLastContact .= "<br />";
        $StationsLastContact .= $StationLastContact;
        curl_multi_remove_handle($multi, $channel);
    }

    // Close the multi-handle and return our results
    curl_multi_close($multi);

    die($StationsLastContact);