htttpServer结构

http

1、httpServer本质是Swoole_server,其协议解析部分固定使用http协议解析

2、完整的http协议请求会被解析并封装在swoole_http_request对象内

3、所有的http相应都通过swoole_http_response对象封装和发送

注意事项


1、swoole_http_server不接受onReceive回调,但是可以使用Task worker和定时器

2、swoole_http_server可以使用诸如onStart、onWorkerStart等回调

3、response/request对象传递给其他函数是,不要加&引用符号(有可能底层没有销毁)、结束请求一定要销毁

swoole_http_request

$header http请求头部信息。类型为数组,所有key均为小写

$server http请求相关的服务器信息

$get Http请求的post参数,相当于PHP中的$_GET

$post http请求的post参数,相当于php中的$_POST,Content-type限定为application/x-www-form-urlencode

$cookie http请求的cookie参数,相当于PHP中的$_COOKIE

$files Http上传文件的文件信息,相当于PHP中的$_FILES

rawcontent()原始的http POST内容,用于非application/x-www-form-urlencode

swoole_http_response
swoole_http_response::header($key,$value);

设置Http响应的头信息

swoole_http_response::cooke($key,$value=””,$expire=0,$path=”/”,$domian=”/”,$secure=false,$httponly=false);

设置http响应的cookie信息,等效于php的setcookie函数

swoole_http_response::status($code);

设置http响应的状态码,如200,404,503等

swoole_http_response::gzip($level=1);

开启GZIP压缩

swoole_http_response::write($data);

启用http chunk分段向浏览器发送响应内容

swoole_http_response::sendfile($filename);

发送文件到浏览器

swoole_http_response::end($data);

发送http响应

用httpserver模拟简单路由

代码结构

图

simple_route.php

新版本4.4开始命名方式为swoole\http\server

<?php

$http = new Swoole\Http\Server("0.0.0.0",80);
$http->set([
    'worker_num' => 2,
    'daemonize' => false, 'max_request' => 10000, 'dispatch_mode' => 2,
]);
$http->on('request',function(Swoole\Http\Request $request, Swoole\Http\Response $response){
    var_dump($request);
    $response->end("&lt;h1>hello&lt;/h1>");
});

$http->on("start", function (Swoole\Http\Server $server) {
    echo "Swoole http server is started at http://127.0.0.1:9501\n";
});

$http->on('close',function(Swoole\Http\Server $server){
    echo "close";
});

$http->start();

老版本

<?php
/**
 * Created by PhpStorm.
 * User: lancelot
 * Date: 16-7-9
 * Time: 下午6:15
 */

$serv = new swoole_http_server("0.0.0.0", 9501);

$serv->set([
    'worker_num' => 1
]);
$serv->on('Start' , function(){
    swoole_set_process_name('simple_route_master');
});

$serv->on('ManagerStart' , function(){
    swoole_set_process_name('simple_route_manager');
});

$serv->on('WorkerStart' , function(){
    swoole_set_process_name('simple_route_worker');
    var_dump(spl_autoload_register(function($class){
        $baseClasspath = \str_replace('\\', DIRECTORY_SEPARATOR , $class) . '.php';

        $classpath = __DIR__ . '/' . $baseClasspath;
        if (is_file($classpath)) {
            require "{$classpath}";
            return;
        }
    }));

});

$serv->on('Request', function($request, $response) {

    $path_info = explode('/',$request->server['path_info']);

    if( isset($path_info[1]) && !empty($path_info[1])) {  // ctrl
        $ctrl = 'ctrl\\' . $path_info[1];
    } else {
        $ctrl = 'ctrl\\Index';
    }
    if( isset($path_info[2] ) ) {  // method
        $action = $path_info[2];
    } else {
        $action = 'index';
    }

    $result = "Ctrl not found";
    if( class_exists($ctrl) )
    {
        $class = new $ctrl();

        $result = "Action not found";

        if( method_exists($class, $action) )
        {
            $result = $class->$action($request);
        }
    }

    $response->end($result);
});

$serv->start();

ctrl\index.php

<?php
/**
 * Created by PhpStorm.
 * User: lancelot
 * Date: 16-7-9
 * Time: 下午6:37
 */

namespace ctrl;

class Index
{
    public function index($request)
    {
        return "Hello World";
    }
}

ctrl\Login.php

<?php
/**
 * Created by PhpStorm.
 * User: lancelot
 * Date: 16-7-9
 * Time: 下午6:38
 */
namespace ctrl;

class Login
{
    public function login($request)
    {
        $post = isset($request->post) ? $request->post : array();

        // TODO 
        return "login success";
    }
}

reload.sh实现代码热加载(不必关闭所有进程、这样正在访问的程序不会报错)

#!/usr/bin/env bash

ps aux | grep simple_route_master | awk  '{print $2}' | xargs kill -USR1

实现文件上传服务

uploader.php服务端server

<?php
/**
 * Created by PhpStorm.
 * User: lancelot
 * Date: 16-7-9
 * Time: 下午6:16
 */

$serv = new swoole_http_server("127.0.0.1", 9501);

$serv->set([
    'max_package_length' => 200000000,
]);
//上传文件的大小 受到max_package_length的限制
$serv->on('Request', function($request, $response) use($serv) {
    if($request->server['request_method'] == 'GET' )
    {
        return;
    }

    var_dump($request->files);
    $file = $request->files['file'];
    $file_name = $file['name'];
    $file_tmp_path = $file['tmp_name'];

    $upload_path = __DIR__ . '/uploader/';
    if( !file_exists($upload_path) )
    {
        mkdir($upload_path);
    }
    move_uploaded_file($file_tmp_path , $upload_path . $file_name );

    $response->end("<h1>Upload Success!</h1>");
});

$serv->start();

前端html

<!DOCTYPE html>
<html>
<body>

<form action="http://127.0.0.1:9501/" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file" />
    <br />
    <input type="submit" name="submit" value="Submit" />
</form>

</body>
</html>

nginx和swoole的结合

nginx的反向代理的、php和静态文件的请求分流

    server {
        listen       80;
        server_name  swoole.solo365.cn;
       

        #charset koi8-r;

        access_log  logs/access_www.log  main ;
        error_log  logs/error_www.log;    
        root /usr/local/nginx/html/swoole;

      
    location /{
        if(!-e $request_filename){
        rewrite ^/(.^)$ /index.php/$1 last;
        break;
        }
    
    }

    location /static{
        root /usr/local/ningx/html/swoole/public/static;
    }

        location / {
            index  index.php index.html index.htm;
#          #### 密码访问 ####
#           auth_basic "test posernode";
#           auth_basic_user_file /usr/local/nginx/conf/vhost/password; 
            autoindex on;

        }
    location ~\.ico {
          root /root /usr/local/ningx/html/swoole/public;
    }

        error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
         error_page   500 502 503 504  /50x.html;
        location = /50x.html {
        }


        location ~ .+\.php.*$ {
           proxy_pass http://127.0.0.1:9501;
         }


    }
Last modification:January 26, 2020
如果觉得我的文章对你有用,请随意赞赏