大家好,今天和大家共同探讨一下,php的这个异步进程的问题。最近一直在这个东西。
1. 通信协议的整理,这个写的很详细。
https://blog.csdn.net/weixin_36851500/article/details/86180283
2. 异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而,异步方法通常会在另外一个线程中,“真实”地执行着。整个过程,不会阻碍调用者的工作。
3. 多进程或多线程
https://www.2cto.com/kf/201802/719224.html
今天我们就有一个实例来聊聊。邮件发送。
首先我是用workerman框架来写。我们首先要用worker类,来设置任务进程服务端。
一、 任务进程服务端
1、 worker类 text 协议
text 协议可以用于长连接,可以用于短连接。
有些客户端不支持websocket协议,比如和一些非浏览器的客户端通讯,
就需要使用其它协议。
text 协议相对比较简单方便,协议格式为 数据包+换行符,
即在每个数据包末尾加上一个换行符表示包的结束。
/**
* Created by test.php.
* User: gongzhiyang
* Date: 19/1/9
* Time: 9:59 下午
*/
use \Workerman\Worker;
use Workerman\Lib\Timer;
use \Workerman\Connection\AsyncTcpConnection;
include_once __DIR__ . '/vendor/autoload.php';
// task worker,使用Text协议
$task_worker = new Worker('Text://0.0.0.0:19345');
// task进程数可以根据需要多开一些
$task_worker->count = 3; //进程数
$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处理相应的任务逻辑.... 得到结果,这里省略....
//var_dump($task_data);
//发送邮件
$task_result = mail($task_data["to"],$task_data["subject"],$task_data["message"]);
if ($task_result){
$task_results = "成功";
} else {
$task_results = "成功";
}
// 发送结果
$connection->send($task_results);
};
Worker::runAll();
- 启动 php TaskWorke.php start,我们发现三个进程
- 查看具体进程 php TaskWorke.php status
二 、在workerman中异步调用
这里我们利用workerman 中异步类AsyncTcpConnection开发,
进程服务器我们已经从设置好。这里用异步接口调用进程管理服务器。
- AsyncTcp.php
**
* Created by test1.php.
* User: gongzhiyang
* Date: 19/1/10
* Time: 11:44 下午
*/
use \Workerman\Worker;
use \Workerman\Connection\AsyncTcpConnection;
include_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:2723');
//$worker->onConnect = function($connection){
// echo "完成";
//};
//客户端发起以后回调
$worker->onMessage = function($ws_connection, $message)
{
//循环异步
for($j=0;$j<5;$j++){
// 与远程task服务建立异步连接,ip为远程task服务的ip,如果是本机就是127.0.0.1,如果是集群就是lvs的ip,也就是说Text://127.0.0.1:19345,我们要先设置好可以用。在这里我们已经设置好了任务进程服务端 TaskWorke.php
$task_connection = new AsyncTcpConnection('Text://127.0.0.1:19345');
// 任务及参数数据
$task_data = array('subject'=>'主题', 'to'=>'xxxxxxx@163.com', 'message'=>'test');
// 发送数据
$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();
}
- 启动服务 php AsyncTcp.php start
三、test.html 这是调用,方便调用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
<script>
ws = new WebSocket("ws://127.0.0.1:2723");
ws.onopen = function() {
alert("连接成功");
ws.send('toms');
alert("给服务端发送一个字符串:toms");
};
ws.onmessage = function(e) {
alert("收到服务端的消息:" + e.data);
};
</script>
</html>
这样基本就完成,我们看一下具体的效果。点击test.html之后。
我们看一下状态:
php TaskWorke.php status
看一下图我们就知道了,五个进程分发到三个进程中。这样就实现了异步发送,缩短了时间,提高了效率,减轻了服务器的压力.如果滥用多进程的话。服务器也可能会崩溃哦!哈哈哈!
看完这篇文章,应该会加深。如果还是模糊。我认为可以这样理解。
页面调用--->会进入异步服务器-->之后会立即返回结果--->随后转到线程服务器进行业务逻辑处理
本人经验有限,如写的不准确,请指正。最好看着手册。来看我这篇文章更好。希望对大家有所帮助!谢谢!