swoole和ThinkPHP的整合
先上一份在我们系统内部的swoole整合的架构预览
├─Application 应用目录
│ │
│ ├─Cli Cli模块
│ │ ├─Controller 制器类
│ │ │ ├─StartController TP框架加载时默认加载的控制器
│ │ │ ├─SwooleController 我们的业务逻辑写在这里面
│ │ └─ ...
├─Swoole
│ │
│ ├─log swoole运行日志
│ ├─Server.php swoole的服务代码
│ ├─swoole.php 用于cli模式下启动和软重启swoole服务
最早测试的时候不是这样搭建的,而是把Server.php里的关于服务的东西放在了TP控制器里,在cli模式下调用
php index.php(入口文件) Swoole/start (控制器/方法)
这种模式是把swoole套在了TP里运行,也是可行的,但是总觉得启动个swoole服务为毛还要告诉TP一声?
我们想要的一种模式是业务服务器独立运行,swoole服务作为守护进程常驻内存,当浏览器需要运行比较耗时的操作时,需要跟swoole服务进程建立长连接,当耗时的任务执行完毕时会通知浏览器已经完毕。
整个过程下来,swoole服务和业务服务不应该耦合在一起的。最完美的状态是swoole独立运行(使用swoole框架重新写耗时操作的业务逻辑代码),独立连接数据库。当浏览器执行这些任务时,就不再找业务服务器了,而是直接跟swoole服务打交道。
可是我们没有那么多的时间和精力,我们只能在swoole服务的进程里调用TP框架的东西,来执行我们在TP里写的代码。最后参考了网上的一些方案,选择了这样与TP结合。
代码逻辑
/Swoole/Server.php
关于swoole服务的一些配置,比如监听地址,端口号(默认为9501),和一些基础配置
一些回调函数,里面的代码注释很完整,可以直接看代码
<?php
// +----------------------------------------------------------------------
// 2017-8-23 09:03:40
// 此次修改为只作为websocket的服务端
// +----------------------------------------------------------------------
class Server{
protected $swoole;
// 监听所有地址
protected $host = '0.0.0.0';
// 监听 9501 端口
protected $port = 9501;
// 配置项
protected $option = [
//设置启动的worker进程数
'worker_num' => 2,
//task进程的数量
'task_worker_num' => 4,
//指定task任务使用消息队列模式,3表示完全争抢模式,task进程会争抢队列,无法使用定向投递
'task_ipc_mode' => 3,
//task进程的最大任务数
'task_max_request' => 1000,
// 守护进程化
'daemonize' => false,
// 监听队列的长度
'backlog' => 128,
//绑定uid时用
'dispatch_mode' => 5,
//设置日志路径
'log_file' => SWOOLE_LOG_PATH,
];
protected function init(){
//异步非阻塞多进程的websocket
$this->swoole = new swoole_websocket_server($this->host, $this->port);
$eventList = ['Open', 'Message', 'Close', 'HandShake' , 'Task', 'Finish' , 'WorkerStart' , 'Receive'];
// 设置参数
if (!empty($this->option)) {
$this->swoole->set($this->option);
}
// 设置回调
foreach ($eventList as $event) {
if (method_exists($this, 'on' . $event)) {
$this->swoole->on($event, [$this, 'on' . $event]);
}
}
}
public function start