国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

請教workerman/http-client用法

Forsend

問題描述

業(yè)務場景:webman開發(fā),提供一個給用戶端調用的api接口,實現(xiàn)邏輯如下:
1、把用戶提交的數(shù)據(jù)處理下,然后請求若干個三方系統(tǒng)的http接口
2、根據(jù)這些三方接口返回的內容,來生成api接口響應數(shù)據(jù)

比如,有3個三方接口A、B、C,都有可能返回我想要的數(shù)據(jù)
如果A響應最快,返回了['IS_A'=> true, 'A DATA' => '...'],那么就直接拿'A DATA'處理下生成接口響應數(shù)據(jù)。B、C的響應結果直接丟棄不用
如果A響應最快,但是返回了['IS_A' => false],那么就繼續(xù)等待下一個最先響應、并且'IS_X'是true的三方接口

為此你搜索到了哪些方案及不適用的原因

現(xiàn)在要求就是這個api接口,性能要高,速度要快(假設這些三方接口本身響應都足夠快)
然后搜了下站內很多帖子,都是推薦用workerman/http-client
但是我不太清楚,怎么才能最好的實現(xiàn)我想要的效果

已經用了workermanV5、http-client2.0、revolt/event-loop
截圖

<?php

namespace app\controller;

use support\Request;

class ApiController
{
    public function index(Request $request)
    {
        $http = new \Workerman\Http\Client();

        // 怎么實現(xiàn)下面代碼的業(yè)務
        // 但是三方接口1,和三方接口2能同時請求,節(jié)省時間
        // 哪個先返回我想要的結果,接口就響應哪個數(shù)據(jù)

        $resp1 = $http->get('三方接口1');
        $data1 = json_decode($resp1->getBody(), true);
        if ($data1['success']) {
            return json(['data' => $data1['data']]);
        }

        $resp2 = $http->get('三方接口2');
        $data2 = json_decode($resp2->getBody(), true);
        if ($data2['success']) {
            return json(['data' => $data2['data']]);
        }

        return json(['data' => null]);
    }
}
2048 1 6
1個回答

walkor 打賞

這種情況用curl_multi就可以,下面代碼是讓webman AI的gpt4生成的,你試下

<?php
// 要請求的URL列表
$urls = [
    'http://example.com',
    'http://example.org',
    'http://example.net'
];

// 初始化多個CURL句柄
$multiCurl = curl_multi_init();
$curlArray = array();

foreach ($urls as $i => $url) {
    $curlArray[$i] = curl_init($url);
    curl_setopt($curlArray[$i], CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multiCurl, $curlArray[$i]);
}

// 執(zhí)行批處理句柄
$index=null;
do {
    while (($execrun = curl_multi_exec($multiCurl, $index)) == CURLM_CALL_MULTI_PERFORM);
    if ($execrun != CURLM_OK) break;
    // 一旦有一個請求完成,找出是哪個請求
    while ($done = curl_multi_info_read($multiCurl)) {
        // 獲取信息和內容
        $info = curl_getinfo($done['handle']);
        if ($info['http_code'] == 200)  {
            $output = curl_multi_getcontent($done['handle']);

            //關閉句柄
            foreach ($urls as $i => $url) {
                curl_multi_remove_handle($multiCurl, $curlArray[$i]);
                curl_close($curlArray[$i]);
            }
            curl_multi_close($multiCurl);

            // 返回獲取的輸出
            return $output;
        }
    }
    // 如果沒有請求完成,就暫時掛起連接
    if ($index > 0) {
        curl_multi_select($multiCurl);
    }
} while ($index > 0);

// 如果所有請求都沒有成功,關閉CURL句柄并返回false
foreach ($urls as $i => $url) {
    curl_multi_remove_handle($multiCurl, $curlArray[$i]);
    curl_close($curlArray[$i]);
}
curl_multi_close($multiCurl);
return false;
  • Forsend 2023-12-21

    謝謝解答,我先試下。
    請問我的這種需求,沒必要用workerman/http-client么?
    搜了站內一些帖子,感覺我的需求跟這個好像差不多,不是用異步協(xié)程http可以提高性能么
    http://m.wtbis.cn/q/11997

  • walkor 2023-12-21

    異步或者協(xié)程性能好一些,但是要求業(yè)務不能使用全局變量(包括靜態(tài)成員)存儲請求相關的狀態(tài)數(shù)據(jù),否則會導致邏輯錯亂。
    下面是webman協(xié)程用法

        public function index(Request $request)
        {
            $urls = [
                'https://www.163.com',
                'https://www.bing.com',
                'https://example.com'
            ];
            $http = new \Workerman\Http\Client();
            $suspension = EventLoop::getSuspension();
            foreach ($urls as $url) {
                $http->get($url, function ($response) use ($suspension, $http) {
                    $data = (string)$response->getBody();
                    if (strpos($data, 'Example Domain')) { // 假設返回中必須有Example Domain才算成功
                        $suspension->resume($data);
                    }
                });
            }
            $data = $suspension->suspend();
            return response($data);
        }
  • Forsend 2023-12-21

    Error: Must call suspend() before calling resume() in /home/web/webman-co/vendor/revolt/event-loop/src/EventLoop/Internal/DriverSuspension.php:52
    Stack trace:

    0 /home/web/webman-co/app/controller/ApiController.php(60): Revolt\EventLoop\Internal\DriverSuspension->resume()

    1 [internal function]: app\controller\ApiController->app\controller{closure}()

    2 /home/web/webman-co/vendor/workerman/http-client/src/Client.php(181): call_user_func()

    3 [internal function]: Workerman\Http\Client->Workerman\Http{closure}()

    4 /home/web/webman-co/vendor/workerman/http-client/src/Emitter.php(120): call_user_func_array()

    5 [internal function]: Workerman\Http\Emitter->emit()

    6 /home/web/webman-co/vendor/workerman/http-client/src/Request.php(130): call_user_func_array()

    7 /home/web/webman-co/vendor/workerman/http-client/src/Request.php(449): Workerman\Http\Request->emit()

    8 /home/web/webman-co/vendor/workerman/http-client/src/Request.php(376): Workerman\Http\Request->emitSuccess()

    9 /home/web/webman-co/vendor/workerman/http-client/src/Request.php(360): Workerman\Http\Request->handleData()

    10 /home/web/webman-co/vendor/workerman/http-client/src/Request.php(327): Workerman\Http\Request->checkComplete()

    11 /home/web/webman-co/vendor/workerman/workerman/src/Connection/TcpConnection.php(725): Workerman\Http\Request->onMessage()

    12 /home/web/webman-co/vendor/workerman/workerman/src/Events/Revolt.php(146): Workerman\Connection\TcpConnection->baseRead()

    13 /home/web/webman-co/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(589): Workerman\Events\Revolt->Workerman\Events{closure}()

    14 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->Revolt\EventLoop\Internal{closure}()

    15 /home/web/webman-co/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(497): Fiber->resume()

    16 /home/web/webman-co/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(553): Revolt\EventLoop\Internal\AbstractDriver->invokeCallbacks()

    17 [internal function]: Revolt\EventLoop\Internal\AbstractDriver->Revolt\EventLoop\Internal{closure}()

    18 /home/web/webman-co/vendor/revolt/event-loop/src/EventLoop/Internal/AbstractDriver.php(113): Fiber->start()

    19 /home/web/webman-co/vendor/revolt/event-loop/src/EventLoop/Driver/EventDriver.php(119): Revolt\EventLoop\Internal\AbstractDriver->run()

    20 /home/web/webman-co/vendor/workerman/workerman/src/Events/Revolt.php(88): Revolt\EventLoop\Driver\EventDriver->run()

    21 /home/web/webman-co/vendor/workerman/workerman/src/Worker.php(1594): Workerman\Events\Revolt->run()

    22 /home/web/webman-co/vendor/workerman/workerman/src/Worker.php(1394): Workerman\Worker::forkOneWorkerForLinux()

    23 /home/web/webman-co/vendor/workerman/workerman/src/Worker.php(1368): Workerman\Worker::forkWorkersForLinux()

    24 /home/web/webman-co/vendor/workerman/workerman/src/Worker.php(572): Workerman\Worker::forkWorkers()

    25 /home/web/webman-co/vendor/workerman/webman-framework/src/support/App.php(131): Workerman\Worker::runAll()

    26 /home/web/webman-co/start.php(4): support\App::run()

    27 {main}

    worker[webman:9729] exit with status 64000

    這樣運行之后會報錯。

  • kspade 2023-12-21

    guzzle 萬能

  • walkor 2023-12-21

    Must call suspend() before calling resume() 意思是你必須在resume()被調用之前調用suspend(),你檢查下你的代碼。
    如果搞不懂就用curl_multi

  • 無法埋名 2024-03-14

    guzzle 更方便

年代過于久遠,無法發(fā)表回答
??