对于一个PHPer来说,解决一些异步,多线程任务,或者Sockets服务,官方标准库还暂时不全面支持.我们一般使用Swoole,WorkMan来解决这类异步方案.
博主主要分享一下Swoole使用经验:其实你会发现现在Swoole文档还是那么难看懂,主要是因为PHPer很多都基于Web应用(前端业务)起底,对于一些进程化,多线程化的很少接触.所以接触起来就比较麻烦.Swoole是使用C语言封装,只支持linux操作系统的php扩展[so].
扩展安装部分请参考文档,应该很详细了,PS:安装时注意下编译参数按需求选择!
在以上安装好了后,注意使用php -m查看swoole是否加入模块.
1.TCP服务器[暂时以同步描述]:
Swoole建立TCP服务,其实有一整个生命周期流程:
以下为Swoole启动流程核心代码:
实例化>>>>绑定监听端口>>>>配置初始化>>>>注册服务开始事件>>>>注册当建立连接事件>>>>注册接收到消息处理>>>>注册任务投递事件>>>>注册任务完成回调事件>>>>注册连接关闭事件[这里是服务器主动或者客户端主动关闭连接]
<?php
class SwooleServer{
private $serv;
public function __construct(){
$this->serv = new Swoole\Server("127.0.0.1", 9501);
$this->serv->set(array(
'worker_num' => 8, //工作进程数量
'daemonize' => false, //是否作为守护进程
'max_request' => 10000,
'dispatch_mode' => 2,
'task_worker_num' => 8
));
$this->serv->on('WorkerStart',array($this,'WorkerStart'));
$this->serv->on('Connect',array($this,'onConnect'));
$this->serv->on('Receive',array($this,'onReceive'));
$this->serv->on('Task',array($this,'onTask'));
$this->serv->on('Finish',array($this,'onFinish'));
$this->serv->on('Close', array($this,'onClose'));
$this->serv->start();
}
public function WorkerStart($serv,$worker_id){
echo "start\r\n";
// 只有当worker_id为0时才添加定时器
// 这里注意,也是初始化的时候可以添加自定义组件注册
if( $worker_id == 0 ) {
//添加定时器
}
}
public function onConnect($serv,$fd,$from_id){
echo " client {$fd} connect\r\n";
}
public function onReceive(swoole_server $serv,$fd,$from_id,$data){
echo "get MESSAGE {$fd} {$data}\r\n";
$data = [
'id' => 1,
"data" => $data,
"fd" => $fd
];
$this->serv->task(json_encode($data));
}
public function onTask($serv,$task_id,$from_id,$data){
echo "This Task {$task_id} from worker {$from_id}";
$data = json_decode($data,true);
echo "Data:{$data['data']}";
$serv->send($data['fd'],"hello");
return "finish";
}
public function onClose($serv,$fd,$from_id){
echo "close";
}
public function onFinish($serv,$task_id,$data){
echo "finish";
echo "result : {$data}";
}
}
new SwooleServer();
?>
以上一些参数解释:
$serv:swoole服务标识,
$fd : 标识连接
$from_id : 标识线程id
$task_id : 这里就是任务投递时,Swoole会分配一个任务id,并投递到某个线程下去执行作业[请看代码]
$data : 任务数据传递对象
所以看上面代码可以一目了然,它的生命周期。将相应的事件与回调带入其中进行扩展就可以使用了,有些参数请结合当前服务器硬件资源设置.
这里注意,错误事件监听回调事件最好也实现掉,统一处理错误,写日志等.
2.Web服务器:
这里其实我觉得不需要讲很多:
初始化网关,端口>>>>注册请求,与响应事件>>>>启动服务
$http = new swoole_http_server("0.0.0.0", 9501);
$http->on('request', function ($request, $response) {
var_dump($request->get, $request->post);
$response->header("Content-Type", "text/html; charset=utf-8");
$response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
});
$http->start();
参数说明:
$request : 请求对象,类似HttpRequest对象,通过访问对象内部属性,获取请求头与其他报文,
$respose : 响应对象,类似于HttpResponse对象,通过$response响应结果输出.
3.定时器
定时器这块可能不需要说太多,
主要注意是 : 定时器要在onWorkerStart中判断$worker_id == 0时注册定时器,与回调任务[上面代码有标记].
4.WebSockets
请参考这里 : https://github.com/ycc297876771/Swoole
以上为快速上手Swoole简要说明: 请各位看了后也不断练习测试,希望早点熟练用上此框架,
内部一些消息传递机制 : 比如共享内存,管道机制,大部分是底层语言结合内存地址标量访问实现的,因为多进程任务暂时无法达到资源完全共享.那么用于信息交换存放的内存空间有限,交换的消息存储并不是无限大.请各位博友悉知.具体还是需要查看官方文档,有些使用规范还是要了解清楚的!!!!
其实快速入门Swoole先需要掌握框架的生命周期,每个事件监控可以做些什么事情.就可以很快入门了~ 还可以参考
easyswoole(请有空看看框架Boot机制就明白了):
https://github.com/easy-swoole/easyswoole 快速上手,不过建议通读几遍官方文档.
如有简要描述性错误,请给博主留言哦~!