1. 程式人生 > >Swoole學習筆記(三):HttpServer

Swoole學習筆記(三):HttpServer

etc tmp http oss 通過 下劃線 靜態 https redirect

1.SW的HttpServer
HttpServer的本質仍然是swoole_server,其協議加些部分固定使用Http協議解析,支持同步和異步2種模式
技術分享圖片
完整的HTTP協議請求會被封裝在swoole_http_request對象內,所有HTTP響應都會通過swoole_http_response對象進行封裝和發送
無論是同步模式還是異步模式,HttpServer都可以維持大量TCP客戶端連接。同步/異步僅僅體現在對請求的處理方式上。
示例:

use Swoole\Http\Server;
$http = new Server("127.0.0.1", 9501);
$http->on(‘request‘, function ($request, $response) {
    $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
});
$http->start();

2.回調函數onRequest事件
函數原型:function(swoole_http_request $request, swoole_http_response $response)
示例:

$http_server->on(‘request‘, function(swoole_http_request $request, swoole_http_response $response) {
     $response->end("<h1>hello swoole</h1>");
})

在收到一個完整的Http請求後,會回調此函數。回調函數共有2個參數:
$request,Http請求信息對象,包含了header/get/post/cookie等相關信息

$response,Http響應對象,支持cookie/header/status等Http操作
在onRequest回調函數返回時底層會銷毀$request和$response對象,如果未執行$response->end()操作,底層會自動執行一次$response->end("")
需要註意的是,將$request/$response傳遞給其他函數時,不要采用引用的方式。在正常情況下,在一個請求流程結束後,這兩個對象的引用次數會被置為0,對象能正常被銷毀。如果有額外的引用的話,那麽對象便不能被銷毀,會造成OOM。當需要傳遞引用時,一定要在請求的最後unset掉這兩個變量。

3.Request
Http請求對象,保存了Http客戶端請求的相關信息,包括GET、POST、COOKIE、Header等;
1)Http\Request->$header
請求的頭部信息。類型為數組,所有key均為小寫。

echo $request->header[‘host‘];
echo $request->header[‘accept-language‘];

2)Http\Request->$server
Http請求相關的服務器信息,相當於PHP的$_SERVER數組。包含了Http請求的方法,URL路徑,客戶端IP等信息。
數組的key全部為小寫,並且與PHP的$_SERVER數組保持一致
echo $request-&gt;server[‘request_time‘];
3)Http\Request->$get
請求的GET參數,相當於PHP中的$_GET,格式為數組。
echo $request-&gt;get[‘hello‘];
註意:為防止HASH***,GET參數最大不允許超過128個
4)Http\Request->$post
POST參數,格式為數組。
echo $request-&gt;post[‘hello‘];
註意:POST與Header加起來的尺寸不得超過package_max_length的設置,否則會認為是惡意請求;同樣的,POST參數的個數最大不超過128個
5)Http\Request->$cookie
HTTP請求攜帶的COOKIE信息,格式為鍵值對數組。
echo $request-&gt;cookie[‘username‘];
6)Http\Request->$files
文件上傳信息。類型為以form名稱為key的二維數組。與PHP的$_FILES相同。最大文件尺寸不得超過package_max_length設置的值。
示例:
[
[name] => facepalm.jpg, //瀏覽器上傳時傳入的文件名稱
[type] => image/jpeg, //MIME類型
[tmp_name] => /tmp/swoole.upfile.n3FmFr,//上傳的臨時文件,文件名以/tmp/swoole.upfile開頭
[error] => 0,//文件尺寸
[size] => 15476
]
7)Http\Request->rawContent
獲取原始的POST包體,用於非application/x-www-form-urlencoded格式的Http POST請求,如application/json。
8)Http\Request->getData
獲取完整的原始Http請求報文。包括Http Header和Http Body
function swoole_http_request-&gt;getData() : string

4.Response
Http響應對象,通過調用此對象的方法,實現Http響應發送。
當Response對象銷毀時,如果未調用end發送Http響應,底層會自動執行end
1)Http\Response->header
設置HTTP響應的Header信息。
function Http\Response->header(string $key, string $value, bool $ucwords = true);
$key,Http頭的Key;$value,Http頭的Value;$ucwords 是否需要對Key進行Http約定格式化,默認true會自動格式化
註意事項:
header設置必須在end方法之前
$key必須完全符合Http的約定,每個單詞首字母大寫,不得包含中文,下劃線或者其他特殊字符
$value必須填寫
$ucwords 設為true,swoole底層會自動對$key進行約定格式化
2)Http\Response->cookie
設置HTTP響應的cookie信息。此方法參數與PHP的setcookie完全一致。
function Http\Response-&gt;cookie(string $key, string $value = ‘‘, int $expire = 0 , string $path = ‘/‘, string $domain = ‘‘, bool $secure = false , bool $httponly = false);
註意事項:
底層自動會對$value進行urlencode編碼,可使用rawCookie關閉對$value的編碼處理;底層允許設置多個相同$key的COOKIE
3)Http\Response->status
發送Http狀態碼。
swoole_http_response-&gt;status(int $http_status_code);
註意事項:
$http_status_code必須為合法的HttpCode,如200, 502, 301, 404等,否則會報錯
4)Http\Response->redirect
發送Http跳轉。調用此方法會自動end發送並結束響應。參數$http_code:狀態碼,默認為302臨時跳轉,傳入301表示永久跳轉
function Http\Response-&gt;redirect(string $url, int $http_code = 302);
5)Http\Response->sendfile
發送文件到瀏覽器。
function Http\Response-&gt;sendfile(string $filename, int $offset = 0, int $length = 0);
$filename 要發送的文件名稱,文件不存在或沒有訪問權限sendfile會失敗
底層無法推斷要發送文件的MIME格式因此需要應用代碼指定Content-Type
調用sendfile前不得使用write方法發送Http-Chunk
調用sendfile後底層會自動執行end
sendfile不支持gzip壓縮
$offset 上傳文件的偏移量,可以指定從文件的中間部分開始傳輸數據。此特性可用於支持斷點續傳。
$length 發送數據的尺寸,默認為整個文件的尺寸
6)Http\Response->write
啟用Http Chunk分段向瀏覽器發送相應內容。關於Http Chunk可以參考Http協議標準文檔。
bool Http\Response->write(string $data);
$data要發送的數據內容,最大長度不得超過2M,受buffer_output_size配置項控制
使用write分段發送數據後,end方法將不接受任何參數
調用end方法後會發送一個長度為0的Chunk表示數據傳輸完畢
7)Http\Response->end
發送Http響應體,並結束請求處理。
function Http\Response->end(string $html);
end操作後將向客戶端瀏覽器發送HTML內容
end只能調用一次,如果需要分多次向客戶端發送數據,請使用write方法
客戶端開啟了KeepAlive,連接將會保持,服務器會等待下一次請求
客戶端未開啟KeepAlive,服務器將會切斷連接

8)nginx反向代理
可以用swoole處理php請求,nginx處理靜態資源,css,圖片等等

server {
    listen 80;
    server_name swoole.test;
    index index.html index.htm index.php
    root /path/to/project

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

    location /Public {
        root /path/to/project
    }

    location ~ \.ico {
        root /path/to/project
    }

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

Swoole學習筆記(三):HttpServer