## **一,HTTP服务器创建** ``` <?php // +---------------------------------------------------------------------- // | najing [ 通用后台管理系统 ] // +---------------------------------------------------------------------- // | Copyright (c) 2020 http://www.najingquan.com All rights reserved. // +---------------------------------------------------------------------- // | Author: 救火队队长 // +---------------------------------------------------------------------- namespace server; /** * 概要描述:HTTP服务器 * @author: 救火队队长 * @since: 2020-05-23 22:45 */ class HttpServer { protected $serv = null; //Swoole\Server对象 protected $host = '0.0.0.0'; //监听对应外网的IP 0.0.0.0监听所有ip protected $port = 9603; //监听端口号 public function __construct() { $this->serv = new \Swoole\Http\Server($this->host, $this->port); //设置参数 //如果业务代码是全异步 IO 的,worker_num设置为 CPU 核数的 1-4 倍最合理 //如果业务代码为同步 IO,worker_num需要根据请求响应时间和系统负载来调整,例如:100-500 //假设每个进程占用 40M 内存,100 个进程就需要占用 4G 内存 $this->serv->set(array( 'worker_num' => 4, //设置启动的worker进程数。【默认值:CPU 核数】 'max_request' => 10000, //设置每个worker进程的最大任务数。【默认值:0 即不会退出进程】 'daemonize' => 0, //开启守护进程化【默认值:0】 )); //监听服务器启动事件 $this->serv->on('start', function ($server) { echo "Swoole http server is started"; }); //监听请求,HTTP服务器只需要关注请求响应即可 //当有新的 HTTP 请求进入就会触发此事件 //$request 对象,包含了请求的相关信息 //$response 对象,对 request 的响应可以通过操作 response 对象来完成。 //$response->end() 方法表示输出一段 HTML 内容,并结束此请求 $this->serv->on('request', function ($request, $response) { // 使用 Chrome 浏览器访问服务器,会产生额外的一次请求,/favicon.ico,可以在代码中响应 404 错误。 if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') { $response->end(); return; } //打印请求的header var_dump($request->header); //打印请求的get参数 var_dump($request->get); //输出返回内容 $response->header("Content-Type", "text/html; charset=utf-8"); $response->end("我是Swoole HTTP服务器输出的返回内容\n"); }); //启动服务 $this->serv->start(); } } $httpServer = new HttpServer(); ``` ## **二,运行HTTP服务** >[danger] **需要用php CLI模式运行** ![](https://img.kancloud.cn/a6/7e/a67e35fb7c32d05b045599dcd3b98dfa_997x243.png) ## **三,访问HTTP服务** 浏览器访问应用地址,会输出HTTP服务返回的内容 ![](https://img.kancloud.cn/11/09/1109f0390c04b45081ec4b871ffa6de1_901x219.png) HTTP服务端会打印客户端request的数据,并输出响应内容 ![](https://img.kancloud.cn/95/0f/950f28439cab0cc29bce512a1a3416f7_1268x377.png) ## **四,URL路由** 应用程序可以根据`$request->server['request_uri']`实现路由。如:`http://najingquan.com:9603/test/index/?a=1`,代码中可以这样实现`URL`路由。 ``` <?php // +---------------------------------------------------------------------- // | najing [ 通用后台管理系统 ] // +---------------------------------------------------------------------- // | Copyright (c) 2020 http://www.najingquan.com All rights reserved. // +---------------------------------------------------------------------- // | Author: 救火队队长 // +---------------------------------------------------------------------- namespace server; /** * 概要描述:HTTP服务器 * @author: 救火队队长 * @since: 2020-05-23 22:45 */ class HttpServer { protected $serv = null; //Swoole\Server对象 protected $host = '0.0.0.0'; //监听对应外网的IP 0.0.0.0监听所有ip protected $port = 9603; //监听端口号 public function __construct() { $this->serv = new \Swoole\Http\Server($this->host, $this->port); //设置参数 //如果业务代码是全异步 IO 的,worker_num设置为 CPU 核数的 1-4 倍最合理 //如果业务代码为同步 IO,worker_num需要根据请求响应时间和系统负载来调整,例如:100-500 //假设每个进程占用 40M 内存,100 个进程就需要占用 4G 内存 $this->serv->set(array( 'worker_num' => 4, //设置启动的worker进程数。【默认值:CPU 核数】 'max_request' => 10000, //设置每个worker进程的最大任务数。【默认值:0 即不会退出进程】 'daemonize' => 0, //开启守护进程化【默认值:0】 )); //监听服务器启动事件 $this->serv->on('start', function ($server) { echo "Swoole http server is started"; }); //监听请求,HTTP服务器只需要关注请求响应即可 //当有新的 HTTP 请求进入就会触发此事件 //$request 对象,包含了请求的相关信息 //$response 对象,对 request 的响应可以通过操作 response 对象来完成。 //$response->end() 方法表示输出一段 HTML 内容,并结束此请求 $this->serv->on('request', function ($request, $response) { // 使用 Chrome 浏览器访问服务器,会产生额外的一次请求,/favicon.ico,可以在代码中响应 404 错误。 if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') { $response->end(); return; } //打印请求的header var_dump($request->header); //打印请求的get参数 var_dump($request->get); //输出返回内容 $response->header("Content-Type", "text/html; charset=utf-8"); list($controller, $action) = explode('/', trim($request->server['request_uri'], '/')); //根据 $controller, $action 映射到不同的控制器类和方法 // 控制器首字母大写 $controller = ucfirst($controller); //判断控制器类是否存在 if (file_exists(__DIR__.'/'.str_replace('\\', '/', $controller).'.php')) { require_once __DIR__.'/'.str_replace('\\', '/', $controller).'.php'; $obj= new $controller; //判断控制器方法是否存在 if (!method_exists($obj, $action)) { $response->status(404); $response->end("<meta charset='UTF-8'>兄弟,方法不存在!"); } else { //如果存在此方法,输出结果 $response->end($obj->$action($request)); } } else { $response->status(404); $response->end("<meta charset='UTF-8'>兄弟,方法不存在!"); } }); //启动服务 $this->serv->start(); } } $httpServer = new HttpServer(); ``` ## **五、创建Test控制器** ``` <?php // +---------------------------------------------------------------------- // | najing [ 通用后台管理系统 ] // +---------------------------------------------------------------------- // | Copyright (c) 2020 http://www.najingquan.com All rights reserved. // +---------------------------------------------------------------------- // | Author: 救火队队长 // +---------------------------------------------------------------------- /** * 概要描述:Test控制器 * @author: 救火队队长 * @since: 2020-05-23 22:45 */ class Test { public function index($request) { //返回请求结果 return "<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"; } } ``` 浏览器访问应用地址,会输出HTTP服务返回的内容 ![](https://img.kancloud.cn/89/9c/899c425a0e4eb461385cc76dde9f09cc_897x208.png) 请求不存在的方法时,会提示方法不存在 ![](https://img.kancloud.cn/57/dc/57dca96a03ef0d53d7a9d57927f01b03_653x158.png)