## 存在问题
见下篇 `协程上下文解决request` 问题。
## swoole
[swoole文档](https://wiki.swoole.com/#/start/start_http_server)
本篇讲解使用协程 `http` 方式,参考了下[hyperf/src/server/src/Server.php](https://github.com/hyperf/hyperf/blob/master/src/server/src/Server.php)。
## 使用函数
不使用 [服务器端 (协程风格) HTTP 服务器](https://wiki.swoole.com/#/coroutine/http_server)
使用 [服务器端 (异步风格) HTTP 服务器](https://wiki.swoole.com/#/http_server)
因为[服务器端 (协程风格) HTTP 服务器](https://wiki.swoole.com/#/coroutine/http_server)设置[pid_file](https://wiki.swoole.com/#/server/setting?id=pid_file)是没用的。
用`异步风格` 也可以用协程: [enable_coroutine](https://wiki.swoole.com/#/server/setting?id=enable_coroutine)
## 创建swoole.php
```
<?php
use core\request\PhpRequest;
error_reporting(E_ALL);
ini_set("display_errors","On");
require_once __DIR__ . '/vendor/autoload.php'; // 引入自动加载
require_once __DIR__ . '/app.php'; // 框架的文件
$start = function()
{
Swoole\Runtime::enableCoroutine($flags = SWOOLE_HOOK_ALL);
// 如果你用了CURL PDO之类的客户端 请开启这个客户端协程化
// 详细见文档: https://wiki.swoole.com/#/runtime
// 绑定主机 端口
$http = new Swoole\Http\Server('0.0.0.0', 9501);
$http->set([
// 进程pid文件
'pid_file' => FRAME_BASE_PATH.'/storage/swoole.pid',
'enable_coroutine' => true, // 开启异步协程化 默认开启
'worker_num' => 4 // Worker进程数 跟协程处理有关系 https://wiki.swoole.com/#/server/setting?id=worker_num
]);
$http->on('request', function ($request, $response) {
echo Swoole\Coroutine::getCid().PHP_EOL; // 打印当前协程id
// 文档:https://wiki.swoole.com/#/coroutine/coroutine?id=getcid
// 绑定request 现在这个是有问题 因为容器的单例的 所以request会一直变
(数据错乱)
// 应该使用协程上下文来保存request 下一篇文章会讲
$server = $request->server;
app()->bind(\core\request\RequestInterface::class,function () use ($server){
return PhpRequest::create(
$server['path_info'],
$server['request_method'],
$server
);
},false);
$response->end(
app('response')->setContent( // 响应
app('router')->dispatch( // 路由
app(\core\request\RequestInterface::class) // 请求
)
)->getContent()
);
});
echo 'start ok'.PHP_EOL;
$http->start();
};
$stop = function ()
{
if(! file_exists(FRAME_BASE_PATH.'/storage/swoole.pid'))
return;
$pid = file_get_contents(FRAME_BASE_PATH.'/storage/swoole.pid');
Swoole\Process::kill($pid); // 见文档
};
$handle = $argv[1];
// 启动
if( $handle == 'start')
$start();
// 停止
elseif( $handle == 'stop');
$stop();
```
## 运行
```
php swoole.php start
```
![](https://img.kancloud.cn/1e/bd/1ebd5558d64efe5e0cc40382446b9e4f_1068x472.png)
![](https://img.kancloud.cn/1f/28/1f285c7ab52c9726c910c7c0f506fb0b_925x412.png)
![](https://img.kancloud.cn/a1/fa/a1fa0f54c078424f91c702aa695e3f58_860x264.png)
## 关于协程id重复解释
### 使用ab测试
![](https://img.kancloud.cn/c4/8a/c48a718509d1e6780c29aea257800714_718x90.png)
```
ab -n 8 -c 8 http://127.0.0.1:9501/
```
### 结果
![](https://img.kancloud.cn/9c/5e/9c5e66c640732321dff27c413fcd1265_723x234.png)
`echo Swoole\Coroutine::getCid().PHP_EOL; // 打印当前协程id
`
这里打印了 `协程id`, 你会发现 `协程id` 重复了。
不用担心, `协程id` 这是唯一的,。
是因为设置了 `'worker_num' => 4`。
- 前言
- 基础篇
- 1. 第一步 创建框架目录结构
- 2. 引入composer自动加载
- 3. php自动加载 (解释篇)
- 4. 创建容器 注册树模式
- 5. 关于psr规范解释
- 6. 关于"容器" "契约" "依赖注入" (解释篇)
- 7. 添加函数文件helpers.php
- 8. 初始化请求(Request)
- 9. 响应 (Response)
- 10. 路由一 (路由组实现)
- 11. 路由二 (加入中间件)
- 12. 配置信息 (类似laravel)
- 13. 数据库连接 (多例模式)
- 14. 查询构造器 (query builder)
- MVC实现
- M 模型实现 (数据映射 + 原型 模式)
- C 控制器实现 + 控制器中间件
- V 视图实现 (Laravel Blade 引擎)
- V 视图切换成 ThinkPhp 模板 引擎)
- 其他轮子
- 日志
- 自定义异常 (异常托管)
- 单元测试 (phpunit)
- 替换成swoole的http服务器
- 协程上下文解决request问题
- qps测试
- 发布到packagist.org