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

關(guān)于異步tcp的問題

小陽光
  • 異步tcp我認(rèn)為的是,tcp請求會做到異步化,tcp發(fā)起請求后,程序自己可以處理其他業(yè)務(wù),tcp有結(jié)果了就執(zhí)行回調(diào)函數(shù),但是通過我的實(shí)驗(yàn)并不是。不知道是我代碼有問題還是怎么回事,求解答。

    $task = new Worker();
    $task->onWorkerStart = function ($task) {
    $connection_to_baidu = new AsyncTcpConnection('tcp://xx.xx.xx.xxx:80');
    $connection_to_baidu->onConnect = function ($connection_to_baidu) {
        echo "connect success\n";
        $connection_to_baidu->send("GET /Mapi/v3/Test/test HTTP/1.1\r\nHost: xx.xx.xx.xxx\r\nConnection: keep-alive\r\n\r\n");
    };
    $connection_to_baidu->onMessage = function ($connection_to_baidu, $http_buffer) {
        echo $http_buffer;
    };
    $connection_to_baidu->onClose = function ($connection_to_baidu) {
        echo "connection closed\n";
    };
    $connection_to_baidu->onError = function ($connection_to_baidu, $code, $msg) {
        echo "Error code:$code msg:$msg\n";
    };
    $connection_to_baidu->connect(); //通過抓包分析,此處會與服務(wù)器三次握手
    
    //模擬處理正常其他業(yè)務(wù) 此處業(yè)務(wù)耗時大于3秒
    for ($i = 0; $i < 30000; $i++) {
        echo $i . PHP_EOL;
        file_get_contents('workerman.log'); //為了防止此處,一直占用cpu資源,做io操作,讓cpu有機(jī)會去執(zhí)行回調(diào)函數(shù)
    }
    //此時會打印connect success, 抓包此處才會發(fā)起http請求   發(fā)送$connection_to_baidu->send("GET /Mapi/v3/Test/test HTTP/1.1\r\nHost: xx.xx.xx.xxx\r\nConnection: keep-alive\r\n\r\n");
    //因?yàn)榻涌趕leep睡眠了三秒返回,此處會有大概三秒等待,然后會執(zhí)行onMessage回調(diào)函數(shù) 打印結(jié)果到控制臺
    };
    // 運(yùn)行worker
    Worker::runAll();
2800 2 1
2個回答

walkor 打賞

workerman運(yùn)行可以認(rèn)為分為2個狀態(tài),一個是執(zhí)行業(yè)務(wù)狀態(tài),一個是workerman內(nèi)核態(tài)狀態(tài),2個狀態(tài)是串行的,并不會并發(fā)執(zhí)行。

執(zhí)行業(yè)務(wù)狀態(tài)也就是進(jìn)程在運(yùn)行業(yè)務(wù)代碼時的狀態(tài),這時候workerman內(nèi)核沒有控制權(quán);
workerman內(nèi)核狀態(tài)是業(yè)務(wù)執(zhí)行完畢后交出控制權(quán)后workerman內(nèi)核運(yùn)行的狀態(tài);

workerman內(nèi)核狀態(tài)實(shí)際上就是一個event-loop,會監(jiān)聽操作系統(tǒng)發(fā)送給workerman的連接事件、連接可讀可寫、關(guān)閉事件,并觸發(fā)onConnect、onMessage、onClose等。只有在workerman內(nèi)核態(tài)才能接收到這些事件,在執(zhí)行業(yè)務(wù)狀態(tài)無法接收并觸發(fā)這些事件。

這就很好的解釋了為什么上面的代碼為什么在業(yè)務(wù)代碼執(zhí)行完畢后才真正發(fā)出了請求。

如果你想要在執(zhí)行業(yè)務(wù)邏輯的時候通知其它進(jìn)程同步處理業(yè)務(wù)邏輯,你應(yīng)該用同步的方式發(fā)起連接和數(shù)據(jù),然后在需要數(shù)據(jù)的時候讀取它。代碼類似這樣:

$task = new Worker();
$task->onWorkerStart = function ($task) {
    $socket = stream_socket_client('tcp://xx.xx.xx.xxx:80');
    fwrite($socket, "GET /Mapi/v3/Test/test HTTP/1.1\r\nHost: xx.xx.xx.xxx\r\nConnection: keep-alive\r\n\r\n");

    //模擬處理正常其他業(yè)務(wù) 此處業(yè)務(wù)耗時大于3秒
    for ($i = 0; $i < 30000; $i++) {
        echo $i . PHP_EOL;
        file_get_contents('workerman.log'); //為了防止此處,一直占用cpu資源,做io操作,讓cpu有機(jī)會去執(zhí)行回調(diào)函數(shù)
    }

    echo fread($socket, 8192);
};
// 運(yùn)行worker
Worker::runAll();

這樣在你處理業(yè)務(wù)的時候,遠(yuǎn)處的進(jìn)程也在處理。當(dāng)你需要獲得結(jié)果的時候,用fread阻塞等待獲得結(jié)果即可。

如果你想同步的方式發(fā)起請求,異步的方式獲得結(jié)果,可以用下面的方法。

use Workerman\Connection\TcpConnection;
$task = new Worker();
$task->onWorkerStart = function ($task) {
    $socket = stream_socket_client('tcp://xx.xx.xx.xxx:80');
     fwrite($socket, "GET /Mapi/v3/Test/test HTTP/1.1\r\nHost:xx.xx.xx.xxx\r\nConnection: keep-alive\r\n\r\n");
    $connection = new TcpConnection($socket);
    $connection->onMessage = function($connection, $http_buffer){
        echo $http_buffer;
        $connection->close(); // 連接不用了要記得關(guān)閉
    }
    //模擬處理正常其他業(yè)務(wù) 此處業(yè)務(wù)耗時大于3秒
    for ($i = 0; $i < 30000; $i++) {
        echo $i . PHP_EOL;
        file_get_contents('workerman.log'); //為了防止此處,一直占用cpu資源,做io操作,讓cpu有機(jī)會去執(zhí)行回調(diào)函數(shù)
    }
};
// 運(yùn)行worker
Worker::runAll();
  • 暫無評論
小陽光

workerman-json-rpc 的異步客戶端就是你這種方式實(shí)現(xiàn)的異步。我以前認(rèn)為AsyncTcpConnection默認(rèn)就實(shí)現(xiàn)了完全異步化。 感謝作者在百忙之中回答。

  • 暫無評論
年代過于久遠(yuǎn),無法發(fā)表回答
??