workerman如何實現異步任務(附代碼)

下面由workerman使用教程欄目給大家介紹workerman實現異步任務的方法,希望對需要的朋友有所幫助!

workerman如何實現異步任務(附代碼)

1、問題

遇到一個問題,php是單線程,無法實現多線程。現在我需要使用一個場景是多個鏈接使用一個線程,也就是在一個連接進程,再開進程來處理

2、解決方案?

workerman如何實現異步任務。workerman可以幫我解決問題, 給予文檔一個解答

問:?

如何異步處理繁重的業務,避免主業務被長時間阻塞。例如我要給1000用戶發送郵件,這個過程很慢,可能要阻塞數秒,這個過程中因為主流程被阻塞,會影響后續的請求,如何將這樣的繁重任務交給其它進程異步處理。?

答:?

可以在本機或者其它服務器甚至服務器集群預先建立一些任務進程處理繁重的業務,任務進程數可以開多一些,例如cpu的10倍,然后調用方利用AsyncTcpConnection將數據異步發送給這些任務進程異步處理,異步得到處理結果?

任務進程服務端

use?WorkermanWorker; require_once?__DIR__?.?'/Workerman/Autoloader.php'; //?task?worker,使用Text協議 $task_worker?=?new?Worker('Text://0.0.0.0:12345'); //?task進程數可以根據需要多開一些 $task_worker->count?=?100; $task_worker->name?=?'TaskWorker'; //只有php7才支持task->reusePort,可以讓每個task進程均衡的接收任務 //$task->reusePort?=?true; $task_worker->onMessage?=?function($connection,?$task_data) { ?????//?假設發來的是json數據 ?????$task_data?=?json_decode($task_data,?true); ?????//?根據task_data處理相應的任務邏輯....?得到結果,這里省略.... ?????$task_result?=?...... ?????//?發送結果 ?????$connection->send(json_encode($task_result)); }; Worker::runAll();

在workerman中調用

use?WorkermanWorker; use?WorkermanConnectionAsyncTcpConnection; require_once?__DIR__?.?'/Workerman/Autoloader.php'; //?websocket服務 $worker?=?new?Worker('websocket://0.0.0.0:8080'); $worker->onMessage?=?function($ws_connection,?$message) { ????//?與遠程task服務建立異步連接,ip為遠程task服務的ip,如果是本機就是127.0.0.1,如果是集群就是lvs的ip ????$task_connection?=?new?AsyncTcpConnection('Text://127.0.0.1:12345'); ????//?任務及參數數據 ????$task_data?=?array( ????????'function'?=>?'send_mail', ????????'args'???????=>?array('from'=>'xxx',?'to'=>'xxx',?'contents'=>'xxx'), ????); ????//?發送數據 ????$task_connection->send(json_encode($task_data)); ????//?異步獲得結果 ????$task_connection->onMessage?=?function($task_connection,?$task_result)use($ws_connection) ????{ ?????????//?結果 ?????????var_dump($task_result); ?????????//?獲得結果后記得關閉異步連接 ?????????$task_connection->close(); ?????????//?通知對應的websocket客戶端任務完成 ?????????$ws_connection->send('task?complete'); ????}; ????//?執行異步連接 ????$task_connection->connect(); } Worker::runAll();

這樣,繁重的任務交給本機或者其它服務器的進程去做,任務完成后會異步收到結果,業務進程就不會阻塞了。

更多Workerman相關技術文章,請訪問workerman使用教程欄目進行學習!

以上就是

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享