The following columnworkerman usage tutorialwill introduce to you the method of workerman to implement asynchronous tasks. I hope it will be helpful to friends in need!
1. Problem
Encountered a problem. PHP is single-threaded and cannot achieve multi-threading. . Now I need to use a scenario where multiple links use one thread, that is, in one connection process, and then open the process to handle it
2. Solution
How about workererman Implement asynchronous tasks. Workerman can help me solve the problem and give an answer to the document
Question:
How to process heavy business asynchronously to avoid the main business being blocked for a long time. For example, I want to send emails to 1,000 users. This process is very slow and may be blocked for several seconds. Because the main process is blocked during this process, it will affect subsequent requests. How can I hand over such heavy tasks to other processes for asynchronous processing.
Answer:
You can pre-establish some task processes on this machine or other servers or even server clusters to handle heavy business. The number of task processes can be increased, for example, 10 times the CPU, and then call The party uses AsyncTcpConnection to asynchronously send data to these task processes for asynchronous processing, and obtain the processing results asynchronously
Task process server
use Workerman\Worker; 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();
Call in workererman
use Workerman\Worker; use \Workerman\Connection\AsyncTcpConnection; 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();
In this way, heavy tasks are handed over to the process of the local machine or other servers. After the task is completed, the results will be received asynchronously, and the business process will not be blocked.
For more Workerman related technical articles, please visit theWorkerman Tutorialcolumn to learn!
The above is the detailed content of How workerman implements asynchronous tasks (with code). For more information, please follow other related articles on the PHP Chinese website!