swoole學習之: 服務端(異步風格)-TCP/UDP服務器 - Swoole\Server的方法

0x00 Swoole\Server

此大節包含 Swoole\Server 類的全部方法、屬性、配置項以及所有的事件。Swoole\Server 類是所有異步風格服務的基類,後面章節的 Http\ServerWebSocket\ServerRedis\Server 都繼承自它。

0x01 方法

__construct(): 構造函數

用於創建一個異步IO的server對象.

Swoole\Server::__construct(string $host = '0.0.0.0', int $port = 0, int $mode = SWOOLE_PROCESS, int $sockType = SWOOLE_SOCK_TCP):Swoole\Server
  • host: 指定監聽的ip地址, 設置爲0表示系統隨機分配
  • port: 指定監聽的端口, 端口號1024以下需要root權限
  • mode: 啓動模式包括: SWOOLE_PROCESS 多進程模式(默認), SWOOLE_BASE 基本模式
  • sockType: 服務類型

示例:

$server = new \Swoole\Server('0.0.0.0', 0, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);//隨機分配端口
echo $server->port.PHP_EOL;

//可以混合使用UDP/TCP, 同時監聽內網和外網端口
$server->addlistener('127.0.0.1', 9502, SWOOLE_SOCK_TCP);//添加TCP服務, 監聽內網ip地址
$server->addlistener('10.0.2.7', 9502, SWOOLE_SOCK_TCP);//添加 TCP, 監聽外網ip地址
$server->addlistener('0.0.0.0', 9504, SWOOLE_SOCK_UDP);//UDP, 監聽所有ip地址
$server->addlistener('/var/run/myserv.sock', 0, SWOOLE_UNIX_STREAM);//unixSocket Stream
$port = $server->addlistener('127.0.0.1', 9502, SWOOLE_SOCK_TCP | SWOOLE_SSL );//TCP+SSL, 必須配置 ssl_key_file和ssl_cert_file
echo $port->port.PHP_EOL;

$port = $server->addlistener('0.0.0.0', 0, SWOOLE_SOCK_TCP);//隨機分配端口, 並返回端口信息
echo $port->port.PHP_EOL;

set(): 設置運行時的各項參數

服務器啓動後通過 $server->setting 來訪問 Server->set 方法設置的參數數組。

必須在$server->start()之前調用

$server->set(array(
    'reactor_num'   => 2,     // reactor thread num
    'worker_num'    => 4,     // worker process num
    'backlog'       => 128,   // listen backlog
    'max_request'   => 50,
    'dispatch_mode' => 1,
));
var_dump($server->setting);//打印設置
$server->on('Receive', function(){});
$server->on('Packet', function(){});
$server->start();

on(): 服務的事件回調函數

Swoole\Server->on(string $event, mixed $callback): void

重複書寫同一個事件的回調函數, 後面的會覆蓋前面的

  • event: 事件名稱, 不包含on, 不區分大小寫. 常見的有: start, shutdown, workerstart, workerstop, workerexit, connect, receive, pack, close, task, finish等

  • callback: 回調函數, 可以是函數名(字符串),類靜態方法,對象方法數組,匿名函數

$server = new Swoole\Server('127.0.0.1', 9502);
$server->on('start', function($server){
    echo 'Server Started at '.date('Y-m-d H:i:s').PHP_EOL;
});
$server->on('connect', function($server, $fd, $reactor_id){
    echo 'Client id='.$fd.' connected, reactor_id='.$reactor_id.PHP_EOL;
    $server->send($fd, 'Welcome to Swoole Server, your client_id:'.$fd.PHP_EOL);
    //$server->close($fd);
});
$server->on('receive', function($server, $fd, $reactor_id, $data){
    echo 'Received from '.$fd.': '. $data.PHP_EOL;
    $server->send($fd, 'data received'.PHP_EOL);
    $server->close($fd);//收到消息後關閉連接
});
$server->on('close', function($server, $fd){
    echo 'Client id='.$fd.' closed'.PHP_EOL;
});
$server->start();

直接使用telnet測試即可: telnet 127.0.0.1 9502

addListener(): 增加監聽的端口

Swoole\Server->addListener(string $host, int $port, int $sockType = SWOOLE_SOCK_TCP): bool|Swoole\Server\Port
  • 監聽 1024 以下的端口需要 root 權限
  • 主服務器是 WebSocket 或 HTTP 協議,新監聽的 TCP 端口默認會繼承主 Server 的協議設置。必須單獨調用 set 方法設置新的協議纔會啓用新協議
  • 可以使用Server->getClientInfo來獲取某個連接來自哪個端口

listen(): 增加監聽的接口, addListener的別名函數

addProcess(): 增加一個用戶自定義的工作進程

通常用於創建一個特殊的工作進程, 用於監聽、上報或其他特殊的任務。

Swoole\Server->addProcess(Swoole\Process $process): bool

不需要執行start. 在Server啓動時會自動創建進程, 並執行指定的子進程函數

● 注意

  • 創建的子進程可以調用$server對象提供的各個方法, 如: getClientInfo, getClientList, stats
  • Worker/Task進程中可以調用$process提供的方法與子進程進行通信
  • 在用戶自定義進程中可以調用$server->sendMessageWorkder/Task進程通信
  • 用戶進程內不能使用Server->task/taskwait接口
  • 用戶進程內可以使用Server->send/close等接口
  • 用戶進程內硬蛋進行while(true)或EventLoop循環(例如創建某個定時器),否則用戶進程會不停地退出重啓 示例:
$server = new Swoole\Server('127.0.0.1', 9502);
$process = new Swoole\Process(function($process)use($server){
    $socket = $process->exportSocket();//得到當前連接的 Socket 對象
    while(true){//必須循環, 否則用戶進程會不停地退出後重啓
        $msg = $socket->recv();//接收消息
        //給所有該服務器的連接發送信息
        foreach($server->connections AS $conn){
            $server->send($conn, $msg);
        }
    }
}, false ,2, 1);//redirect_stdin_and_stdout, pipe_type, enable_coroutine
$server->addProcess($process);
$server->on('receive', function($server, $fd, $reactor_id, $data)use($process){
    $socket = $process->exportSocket();//得到當前連接的 Socket 對象
    $socket->send($data);
});
$server->start();

未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章