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();

未完待续

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