ThinkPHP 5.1 Swoole 扩展 =============== ## 安装 首先按照Swoole官网说明安装swoole扩展,然后使用 ~~~ composer require topthink/think-swoole ~~~ 安装swoole扩展。 ## 使用方法 ### HttpServer 直接在命令行下启动服务端。 ~~~ php think swoole ~~~ 启动完成后,会在0.0.0.0:9501启动一个HTTP Server,可以直接访问当前的应用。 swoole的参数可以在应用配置目录下的swoole.php里面配置(具体参考配置文件内容)。 如果需要使用守护进程方式运行,可以使用 ~~~ php think swoole -d ~~~ 或者在swoole.php文件中设置 ~~~ 'daemonize' => true ~~~ 注意:由于onWorkerStart运行的时候没有HTTP_HOST,因此最好在应用配置文件中设置app_host 支持的操作包括 ~~~ php think swoole [start|stop|reload|restart] ~~~ ### Server 可以支持直接启动一个Swoole server ~~~ php think swoole:server ~~~ 会在0.0.0.0:9508启动一个Websocket服务。 如果需要自定义参数,可以在config/swoole_server.php中进行配置,包括: 配置参数 | 描述 --- | --- type| 服务类型 host | 监听地址 port | 监听端口 mode | 运行模式 sock_type | Socket type 并且支持swoole所有的参数。 也支持使用闭包方式定义相关事件回调。 ~~~ return [ // 扩展自身配置 'host' => '0.0.0.0', // 监听地址 'port' => 9501, // 监听端口 'type' => 'socket', // 服务类型 支持 socket http server 'mode' => SWOOLE_PROCESS, 'sock_type' => SWOOLE_SOCK_TCP, // 可以支持swoole的所有配置参数 'daemonize' => false, // 事件回调定义 'onOpen' => function ($server, $request) { echo "server: handshake success with fd{$request->fd}\n"; }, 'onMessage' => function ($server, $frame) { echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n"; $server->push($frame->fd, "this is server"); }, 'onRequest' => function ($request, $response) { $response->end("

Hello Swoole. #" . rand(1000, 9999) . "

"); }, 'onClose' => function ($ser, $fd) { echo "client {$fd} closed\n"; }, ]; ~~~ 也可以使用自定义的服务类 ~~~ 4, 'daemonize' => true, 'backlog' => 128 ]; public function onReceive($server, $fd, $from_id, $data) { $server->send($fd, 'Swoole: '.$data); } } ~~~ 支持swoole所有的回调方法定义(回调方法必须是public类型) serverType 属性定义为 socket或者http 则支持swoole的swoole_websocket_server和swoole_http_server 然后在swoole_server.php中增加配置参数: ~~~ return [ 'swoole_class' => 'app\http\Swoole', ]; ~~~ 定义该参数后,其它配置参数均不再有效。 在命令行启动服务端 ~~~ php think swoole:server ~~~ 支持reload|restart|stop|status 操作 ~~~ php think swoole:server reload ~~~ ### 配置信息详解 swoole.php ```php // +---------------------------------------------------------------------- use think\facade\Env; // +---------------------------------------------------------------------- // | Swoole设置 php think swoole命令行下有效 // +---------------------------------------------------------------------- return [ // 扩展自身配置 'host' => '0.0.0.0', // 监听地址 'port' => 9501, // 监听端口 'mode' => '', // 运行模式 默认为SWOOLE_PROCESS 'sock_type' => '', // sock type 默认为SWOOLE_SOCK_TCP 'app_path' => '', // 应用地址 如果开启了 'daemonize'=>true 必须设置(使用绝对路径) 'file_monitor' => false, // 是否开启PHP文件更改监控(调试模式下自动开启) 'file_monitor_interval' => 2, // 文件变化监控检测时间间隔(秒) 'file_monitor_path' => [], // 文件监控目录 默认监控application和config目录 // 可以支持swoole的所有配置参数 'pid_file' => Env::get('runtime_path') . 'swoole.pid',//swoole主进程pid存放文件 'log_file' => Env::get('runtime_path') . 'swoole.log',//swoole日志存放文件 'document_root' => Env::get('root_path') . 'public',//设置静态服务根目录 'enable_static_handler' => true,//是否由SWOOLE底层自动处理静态文件,TRUE表示SWOOLE判断是否存在静态文件,如果存在则直接返回静态文件信息 'timer' => true,//是否开启系统定时器 'interval' => 500,//系统定时器 时间间隔 'task_worker_num' => 1,//swoole 任务工作进程数量 'user' =>'www',//表示swoole worker进程所属的管理员名称,如果要绑定1024以下端口则必须要求具有root权限,如果设置了该项,则除主进程外的所有进程都运行于指定用户下 ]; ``` timer.php ```php "类" * *中间一个空格 * 系统定时任务需要在swoole.php中开启 * 自定义定时器不受其影响 */ return [ '*/5 * * * * *' => '\\app\\lib\\Timer',//时间配置方式参考crontab,主要是增加秒,其他和crontab一致,对应Value为定时器接口实现类的完整命名空间(包含类名) ]; ``` ### 异步任务投递 1.异步任务接口实现 ```php function($server, $worker_id){ //如果只在一个进程处理 则可以这样 if (0==$worker_id){ //这样只会在第一个woker进程处理 } } ``` 如果需要实现Workerstart的接口,可以这样实现 ```php '\\app\\lib\\WorkStart' ``` ### Websocket支持 需要在swoole.php修改 ```a 'server_type' => 'websocket', // 服务类型 支持 http websocket ``` 由于Swoole\WebSocket\Server继承于Swoole\Http\Server顾Http服务具有的功能Websocket也具有。如果采用如下websocket服务, 通讯数据格式已经固定,如采用自定义数据结构,请采用自定义服务 WebSocket通讯数据结构 ```json { "event":"",//事件名称 "url":"",//目标地址 "arguments":{//客户端投递数据 "post":[],//post数据 "get":[],//get数据 "cookie":[],//cookie数据 } } ``` 详解 * event 该参数为事件名称,用于触发客户端事件,即接收服务器推送数据处理指定任务 * url,该为访问的目标地址,相当于http模式下http://xxx.com/url * arguments 客户端投递的所有数据,如果希望可以按照原来POST,GET的方式处理数据,可以提交时按照上述方式提交,会自动处理 客户端JS可以参考example里websocketclient.js 服务端发送数据 ```php use think\swoole\WebSocketFrame; $client=WebSocketFrame::getInstance(); //发送数据给当前请求的客户端 $client->pushToClient([]);//参数为数组,字符串,数字 //发送给所有客户端 $client->pushToClients([]);//参数为数组,字符串,数字 $client->getArgs();//获取arguments里的参数 $client->getData();//获取客户端发送给的所有数据 $client->getServer();//获取当前server $client->getFrame();//获取当前客户端给发送的原始数据 ``` 新增队列支持 think-queue,是一个非常好用的队列服务,xavier-swoole的队列服务依赖于think-queue,使用方法和think-queue保持一致 主要增加如下功能 1. 采用多进程模式运行或采用Task异步执行 2. 可以指定同时消耗队列任务的进程数量 3. Task模式和Server共享Task进程,充分利用资源 4. Process模式采用进程模式,各个任务之间相互隔离,执行一定次数后,重启进程,防止内存泄露 如果任务较多且复杂,推荐采用Process模式 ```php 'queue_type'=>'task',//task or process 'queue'=>[ "Index"=>[ "delay"=>0,//延迟时间 "sleep"=>3,//休息时间 "maxTries"=>0,//重试次数 "nums"=>2//进程数量 ], ] ```