前言
第一部分: 半协程调度器
- 统一生成器接口
- 生成器迭代
- 生成器返回值
- 生成器委托
- 改写 return
- 抽象异步模型
- 引入异常处理
- 异常: 嵌套任务透传
- 异常: 传递流程
- 异常: 重新进行 CPS 变换
- 异常: 重新加入 Async
- Syscall 与 Context
- 调度器: 里程碑
- spawn
- callcc
- race 与 timeout
- all 与 parallel
- channel 与协程间通信
- 无缓存 channel
- 缓存 channel
- channel 演示
- FutureTask 与 fork
第二部分: Koa
- 穿越地心之旅
- 洋葱圈模型
- rightReduce与中间件compose
- Koa::Application
- Koa::Context
- Koa::Request
- Koa::Response
- Koa - HelloWorld
- Middleware Interface
- Middleware: 全局异常处理
- Middleware: Router
- Middleware: 请求超时
- 一个综合示例
附录
参考
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
Koa::Application
接下来我们来看Koa的仅有四个组件,Application
Context
Request
Response
依次给予实现:
Koa::Application
The application object is Koa's interface with node's http server and handles the registration
of middleware, dispatching to the middleware from http, default error handling, as well as
configuration of the context, request and response objects.
我们的App
模块是对swoole_http_server
的简单封装,在onRequest回调中对中间件compose并执行:
<?php
class Application
{
/** @var \swoole_http_server */
public $httpServer;
/** @var Context Prototype Context */
public $context;
public $middleware = [];
public $fn;
public function __construct()
{
// 我们构造一个Context原型
$this->context = new Context();
$this->context->app = $this;
}
// 我们用υse方法添加符合接口的中间件
// middleware :: (Context $ctx, $next) -> void
public function υse(callable $fn)
{
$this->middleware[] = $fn;
return $this;
}
// compose中间件 监听端口提供服务
public function listen($port = 8000, array $config = [])
{
$this->fn = compose($this->middleware);
$config = ['port' => $port] + $config + $this->defaultConfig();
$this->httpServer = new \swoole_http_server($config['host'], $config['port'], SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
$this->httpServer->set($config);
// 省略绑定 swoole HttpServer 事件, start shutdown connect close workerStart workerStop workerError request
// ...
$this->httpServer->start();
}
public function onRequest(\swoole_http_request $req, \swoole_http_response $res)
{
$ctx = $this->createContext($req, $res);
$reqHandler = $this->makeRequestHandler($ctx);
$resHandler = $this->makeResponseHandler($ctx);
spawn($reqHandler, $resHandler);
}
protected function makeRequestHandler(Context $ctx)
{
return function() use($ctx) {
yield setCtx("ctx", $ctx);
$ctx->res->status(404);
$fn = $this->fn;
yield $fn($ctx);
};
}
protected function makeResponseHandler(Context $ctx)
{
return function($r = null, \Exception $ex = null) use($ctx) {
if ($ex) {
$this->handleError($ctx, $ex);
} else {
$this->respond($ctx);
}
};
}
protected function handleError(Context $ctx, \Exception $ex = null)
{
if ($ex === null) {
return;
}
if ($ex && $ex->getCode() !== 404) {
sys_error($ctx);
sys_error($ex);
}
// 非 Http异常, 统一500 status,对外显示异常code
// Http 异常,自定义status,自定义是否暴露Msg
$msg = $ex->getCode();
if ($ex instanceof HttpException) {
$status = $ex->status ?: 500;
$ctx->res->status($status);
if ($ex->expose) {
$msg = $ex->getMessage();
}
} else {
$ctx->res->status(500);
}
// force text/plain
$ctx->res->header("Content-Type", "text"); // TODO accepts
$ctx->res->write($msg);
$ctx->res->end();
}
protected function respond(Context $ctx)
{
if ($ctx->respond === false) return; // allow bypassing Koa
$body = $ctx->body;
$code = $ctx->status;
if ($code !== null) {
$ctx->res->status($code);
}
// status.empty() $ctx->body = null; res->end()
if ($body !== null) {
$ctx->res->write($body);
}
$ctx->res->end();
}
protected function createContext(\swoole_http_request $req, \swoole_http_response $res)
{
// 可以在Context挂其他组件 $app->foo = bar; $app->listen();
$context = clone $this->context;
$request = $context->request = new Request($this, $context, $req, $res);
$response = $context->response = new Response($this, $context, $req, $res);
$context->app = $this;
$context->req = $req;
$context->res = $res;
$request->response = $response;
$response->request = $request;
$request->originalUrl = $req->server["request_uri"];
$request->ip = $req->server["remote_addr"];
return $context;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论