2014-03-26 2 views
3

A. 요약여러 요청을 보낼 때 결과를 요청과 일치시키는 방법은 무엇입니까? 제목으로

는, 폭식은 documentation 같이 시간을 절약하기 위해 한 번에 여러 요청을 보낼 수 있습니다.

$responses = $client->send(array(
    $requestObj1, 
    $requestObj2, 
    ... 
)); 

(given that each request object is an instance of 
Guzzle\Http\Message\EntityEnclosingRequestInterface) 

는 응답은 요청에 대해, 우리는 각 요청을 통해 루프 (위의 명령을 실행 한 후에서만 사용 가능) 응답을 얻을 수있는 응답을 확인하는, 돌아올 때 :

$response1 = $requestObj1->getResponse(); 
$response2 = $requestObj2->getResponse(); 
... 

B 문제

요청 개체에 동일한 데이터가 포함되어있는 경우. 최초 요청을 식별하는 것은 불가능합니다. 거리 서버 A와 B : :

우리가 다음 우리가이 개 기사를 작성해야 시나리오가 있다고 가정 something.com/articles/create.json을

각 요청 같은 POST 데이터가 있습니다

subject: This is a test article 
을 만든 후

, 2 위치와 목구멍의 응답이 돌아올 :

something.com/articles/223.json 
something.com/articles/245.json 

을 응답 투의 요청을 연결하는 위의 방법을 사용하여, 우리는 아직도 모르고있는 응답 내가 요청 개체가 정확히 동일한이기 때문에 어느 문서에 대해 이 있는지 확인하십시오.

따라서 내 데이터베이스에서 나는 결과를 아래로 쓸 수 없습니다 :

article A -> Location: 223.json 
article B -> Location: 245.json 

해결책은 POST 요청에 몇 가지 추가 매개 변수를 넣어하는 것입니다

article A -> Location: 245.json 
article B -> Location: 223.json 

를이 arround를 다른 방법이 될 수 있기 때문에 , 예.

subject: This is a test article 
record: A 

그러나, 거리 서버가 오류를 반환하고 키 "레코드"를 이해하지 않기 때문에 기사를 작성하지 않습니다. 거리 서버는 타사 서버이므로 작동 방식을 변경할 수 없습니다.

또 다른 적절한 해결책은 요청 개체에 특정 ID/태그를 설정하는 것이므로 나중에 식별 할 수 있습니다. 그러나, 나는 문서를 통해 검토 한하지만 방법은 정체성이 문제를 해결할 수없는 여전히

$request->setID("id1") 

or 

$request->setTag("id1") 

이 몇 달 동안 나를 귀찮게되었으며 같은 요청에 유일하게 존재하지 않는다.

해결책이있는 경우 알려 주시기 바랍니다.

많은 많은 감사와 나를 구 했어요 !!

이 긴 게시물을 읽어 주셔서 감사합니다.

+0

사용 사례에 따라 API에 대해 도메인 식별자를 사용합니다. –

답변

1

올바른 방법을 찾았습니다. 요청이 완료되면 Guzz allow 콜백을 추가 할 수 있습니다. 그래서 우리는 그래서 우리가 원하는 것을 달성하기 위해 기본적으로 각 요청이

$request = $client->createRequest('GET', 'http://httpbin.org', [ 
    'headers' => ['X-Foo' => 'Bar'] 
]); 

처럼 만들 수 있습니다

배치에서 각 요청에 설정하여이를 달성 할 수

$allRequests = []; 
$allResults = []; 

for($k=0; $k<=10; $k++){ 
    $allRequests['key_'.$k] = $client->createRequest('GET', 'http://httpbin.org?id='.$k, [ 
     'headers' => ['X-Foo' => 'Bar'], 
     'events' => [ 
      'complete' => function ($e) use (&$allResults, $k){ 
       $response = $e->getResponse(); 
       $allResults['key_'.$k] = $response->getBody().''; 
      } 
     ] 
    ]); 
} 

$client->sendAll(array_values($allRequests)); 

print_r($allResults); 

그래서 이제 $ allResults는 각 해당 요청에 대한 결과를가집니다.

$ allResults [ 'key_1는'] allRequests은 [ 'key_1']

1

나는 이와 동일한 문제가있었습니다.

각 요청에 대해 생성 된 고유 ID가있는 사용자 지정 쿼리 매개 변수를 추가하여 요청 URL에 추가하여 해결했습니다 (이후 각 요청에 대해이 ID를 기억해야합니다).

$responses = $client->send($requests) 후에는 응답을 반복하고 효과적인 URL $response->getEffectiveUrl()를 검색하고 분석 할 수있다 (고유 ID를) 사용자 정의 매개 변수를 얻고 하나를 가지고 요청의 배열에서 검색하는 (parse_urlparse_str 참조).

0

내가이 방법을 $의 결과입니다

// create your requests 
$requests[] = $client->createRequest('GET', '/endpoint', ['config' => ['order_id' => 123]]); 
... 
// in your success callback get 
$id = $event->getRequest()->getConfig()['order_id'] 
0

새로운 GuzzleHttp guzzlehttp 관련 업데이트를/목구멍

동시성/병렬 호출은 이제 약속을 포함한 몇 가지 다른 방법을 통해 실행됩니다. Concurrent Requests

RequestInterfaces의 배열을 전달하는 기존 방법은 더 이상 작동하지 않습니다.

$ requestArr [$ doc-> 참조]를 사용하여 응답의 각을 참조 할 수있을 것이다이 예에서는 여기

$newClient = new \GuzzleHttp\Client(['base_uri' => $base]); 
    foreach($documents->documents as $doc){ 

     $params = [ 
      'language' =>'eng', 
      'text' => $doc->summary, 
      'apikey' => $key 
     ]; 

     $requestArr[$doc->reference] = $newClient->getAsync('/1/api/sync/analyze/v1?' . http_build_query($params)); 
    } 

    $time_start = microtime(true); 
    $responses = \GuzzleHttp\Promise\unwrap($requestArr); //$newClient->send($requestArr); 
    $time_end = microtime(true); 
    $this->get('logger')->error(' NewsPerf Dev: took ' . ($time_end - $time_start)); 

예를 를 참조하십시오. 즉, 배열에 인덱스를주고 Promise :: unwrap 호출을 실행하십시오.

0

나는 훨씬 더 좋은 대답을 발견했습니다.

한 번에 20 건의 요청을 일괄 적으로 보내고 있으며, 동시에 4 건의 요청을 보내고 있으며, 풀링 기법을 사용했습니다.

이 코드를 requestAsync() 함수 호출의 끝에 추가 할 수 있다는 것을 알았습니다. 배열을 생성하거나 작성할 때 (다른 위치에서 모두 수행)이 코드를 추가 할 수 있습니다.

그리고 수영장의 clousers에서 응답의 _source_object에 정상적으로 액세스 할 수 있으며 훌륭하게 작동합니다. 조금 해킹 된 것을 발견하지만, Guzzle에서 절대 충돌하지 않는 이름을 사용해야한다면 잘 될 것입니다.

관련 문제