1. 程式人生 > >Swoole Echo伺服器隨意搭建 及set函式詳解

Swoole Echo伺服器隨意搭建 及set函式詳解

<?php
//Server
Class Server
{
    private $serv;

    /**
     * 連結swoole伺服器
     * Server constructor.
     */
    public function __construct()
    {
        //建立swoole_server物件
        $this->serv = new swoole_server('0.0.0.0', 9501);
        //set函式配置swoole_server
        $this->serv->set([
            'worker_num' => 8, //指定啟動worker的程序數

            'max_request' => 10000, //每個worker程序最大執行處理任務的個數

            'max_conn' => 10000, //伺服器允許維持最大的TCP連線數 不能超過作業系統ulimit -n的值

            'ipc_mode' => 1, //設定程序間的通訊方式 1-使用unix socket連線 2-訊息佇列通訊 3-訊息佇列通訊 並設定為爭搶模式

            'dispath_mode' => 1, //指定資料包分發策略 1-輪詢模式 (輪詢分配給每一個worker程序)
                                                    #2-固定模式 根據連線檔案描述符分配worker 保證同一個連線發來的資料只被一個worker處理
                                                    #3-爭搶模式 主程序會根據每個worker的閒忙程度選擇投遞,只會投遞給閒置狀態的worker程序

            'task_worker_num' => 8, //伺服器開啟task程序數 設定引數後開啟非同步task功能。可以使用task方法投遞非同步任務
                                    //注:設定引數後必須給swoole_server設定onTask/onFinish兩個回撥函式

            'task_max_request' => 10000, //每個task程序最大允許處理任務的個數 參考(max_request)

            'task_ipc_mode' => 2, //設定task程序與worker程序之間的通訊方式  參考(ipc_mode)

            'daemonize' => false, //設定程式進入後臺作為守護程序執行
                                    #注:長時間執行的伺服器端程式必須啟用此項。如果不啟用守護程序,當ssh終端退出後,程式將被終止執行。
                                    #啟用守護程序後,標準輸入和輸出會被重定向到 log_file,如果 log_file未設定,則所有輸出會被丟棄。

            'log_file' => '/data/log/swoole.log', //指定日誌檔案目錄
                                                    #在swoole執行期發生的異常資訊會記錄到這個檔案中。預設會列印到螢幕。
                                                    #注意log_file 不會自動切分檔案,所以需要定期清理此檔案。

            'health_check_interval' => 60, //設定心跳檢測間隔
                                            #此選項表示每隔多久輪循一次,單位為秒。每次檢測時遍歷所有連線,如果某個連線在間隔時間內沒有資料傳送,則強制關閉連線(會有onClose回撥)。

            'heartbeat_idle_time' => 600, //設定某個連線數允許最大的閒置時間
                                            #該引數配合heartbeat_check_interval使用。每次遍歷所有連線時,如果某個連線在heartbeat_idle_time時間內沒有資料傳送,則強制關閉連線。
                                            #預設設定為heartbeat_check_interval * 2。

            'open_eof_check' => true, //開啟eof檢測功能。與package_eof 配合使用。此選項將檢測客戶端連線發來的資料,當資料包結尾是指定的package_eof 字串時才會將資料包投遞至Worker程序,否則會一直拼接資料包直到快取溢位或超時才會終止。
                                        #一旦出錯,該連線會被判定為惡意連線,資料包會被丟棄並強制關閉連線。
                                        #EOF檢測不會從資料中間查詢eof字串,所以Worker程序可能會同時收到多個數據包,需要在應用層程式碼中自行explode("\r\n", $data) 來拆分資料包

            'package_eof' => '\r\n', //設定EOF的字串 最大隻允許傳入8個字串

            'open_length_check' => true, //開啟長包檢測
                                        #包長檢測提供了固定包頭+包體這種格式協議的解析,。啟用後,可以保證Worker程序onReceive每次都會收到一個完整的資料包。

            'package_length_offset' => 5, //包頭中開始字串開始存放了欄位長度
                                          #配合open_length_check使用,用於指明長度欄位的位置。

            'package_body_offset' => 10, //從第幾個字串開始計算長度
                                            #配和open_length_checks使用,用於指明包頭長度

            'package_length_type' => 'N',  #配合open_length_check使用,指定長度欄位的型別,引數如下:
                                           #'s' => int16_t 機器位元組序
                                           #'S' => uint16_t 機器位元組序
                                           #'n' => uint16_t 大端位元組序
                                           #’N‘ => uint32_t 大端位元組序
                                           #'L' => uint32_t 機器位元組序
                                           #'l' => int 機器位元組序

            'package_max_length' => 8192, //設定最大資料包尺寸
                                            #該值決定了資料包快取區的大小。如果快取的資料超過了該值,則會引發錯誤。具體錯誤處理由開啟的協議解析的型別決定。

            'open_cpu_affinity' => true, //啟動cup親和性設定
                                            #在多核的硬體平臺中,啟用此特性會將swoole的reactor執行緒/worker程序繫結到固定的一個核上。
                                            #可以避免程序/執行緒的執行時在多個核之間互相切換,提高CPU Cache的命中率。

            'open_tcp_nodelay' => true, //開啟後TCP連線傳送資料時會無關閉Nagle合併演算法,立即發往客戶端連線。
                                        #在某些場景下,如http伺服器,可以提升響應速度。

            'tcp_defer_accept' => true, //啟動後,只有一個TCP連線有資料傳送時才會觸發accept。

            'ssl_cert_file' => "/config/ssl.crt",  //設定SSL隧道加密
            'ssl_key_file' => "/config//ssl.key",
                                                    #說明:設定值為一個檔名字串,指定cert證書和key的路徑。

            'open_tcp_keepalive' => true, //開啟TCP的KEEP_ALIVE選項
                                            #使用TCP內建的keep_alive屬性,用於保證連線不會因為長時閒置而被關閉。

            'tcp_keepidle' => 600, //指定探測時間 配合open_tcp_keepalive使用,如果某個連線在tcp_keepidle內沒有任何資料來往,則進行探測。

            'tcp_keepinterval' => 60, //指定探測時的發包間隔
                                        #配合open_tcp_keepalive使用

            'tcp_keepcount' => 5,  //指定探測的嘗試次數
                                     #配合open_tcp_keepalive使用,若tcp_keepcount次嘗試後仍無響應,則判定連線已關閉。

            'backlog' => 128, //指定佇列長度
                                #此引數將決定最多同時有多少個等待accept的連線。

            'reactor_num' => 8, //指定Reactor執行緒數
                                  #設定主程序內事件處理執行緒的數量,預設會啟用CPU核數相同的數量, 一般設定為CPU核數的1-4倍,最大不得超過CPU核數*4。

            'task_tmpdir' => '/tmp/task/', //設定task的資料臨時目錄
                                            #如果投遞的資料超過8192位元組,將啟用臨時檔案來儲存資料。這裡的task_tmpdir就是用來設定臨時檔案儲存的位置。

        ]);
        //呼叫on函式設定相關回調函式
        $this->serv->on('Start', [$this, 'onStart']); //開啟    在server執行前呼叫
        $this->serv->on('Connect', [$this, 'onConnect']); //連結  在有新的client客戶端請求時被呼叫
        $this->serv->on('Receive', [$this, 'onReceive']); //接受  有資料被髮送到server時被呼叫
        $this->serv->on('Close', [$this, 'onClose']); //關閉      有客戶端斷開連線時被呼叫

        $this->serv->start();
    }

    /**
     * 開啟
     * @param $serv
     */
    public function onStart($serv)
    {
        echo "Start\n";
    }

    /**
     * 連結
     * @param $serv
     * @param $fd
     * @param $from_id
     */
    //在connect處監聽新的客戶端請求
    public function onConnect($serv, $fd, $from_id)
    {
        $serv->send($fd, "Hello {$fd}!");
    }

    /**
     * 接受
     * @return [type] [deception]
     */
    //在onReceive接受請求並處理
    public function onReceive(swoole_server $serv, $fd, $from_id, $data)
    {
        echo "Get Message From Client {$fd}:{$data}\n";
        //使用send函式將處理結果傳送出去
        $serv->send($fd, $data);
    }

    /**
     * 關閉
     * @return [type] [deception]
     */
    //onClose處理客戶端下線事件
    public function onClose($serv, $fd, $from_id)
    {
        echo "Client {$fd} close connection\n";
    }

}
/*啟動Server*/
$server = new Server();

client(客戶端)

<?php 
Class Client
{
    private $client;

    /**
     * 建立swoole連線
     * Client constructor.
     */
    public function __construct()
    {
        $this->client = new swoole_client(SWOOLE_SOCK_TCP);
    }

    /**
     * 建立連線
     * @return [type] [deception]
     */
    public function connect()
    {
        if( !$this->client->connect('127.0.0.1', 9501, 1)) {
            echo "Error: {$this->client->errMsg}[{$this->client->errCode}]\n";
        }
        fwrite(STDOUT, "客戶端請輸入訊息:");
        $msg = trim(fgets(STDIN));
        $this->client->send($msg);

        $message = $this->client->recv();
        echo "對方Server輸入的資訊是:{$message}\n";
    }
}

/**
 * 開啟連線
 */
$client = new Client();
$client->connect();