-
Notifications
You must be signed in to change notification settings - Fork 18
helpManual swoole
//强制使用网络方式, 保证网络"异步请求回调"也在Swoole中 _of.com.net.isCli = false; //异步请求网络, 注意端口正确 _of.com.net.async = 'http://127.0.0.1:8888/'; //swoole异步任务方式 _of.com.timer.fork.adapter = 'swoole';
<?php //以下为默认配置 return array( //系统配置 'system' => array( //开启服务, 默认支持http的WebSocket协议服务, 绝对路径则为自定义服务(如: /var/www/html/test.php 参考下方demo) 'open' => 'WebSocket', //监听端口, 默认8888 'port' => 8888, //工作进程超过该时间会安全重启, 单位秒, 默认0不限制 'cycle' => 0, //工作进程超过该内存会安全重启, 支持K M G单位(如: 1G), 默认0不限制 'memory' => 0, //启动配置的绝对路径, 仅在启动参数conf为json格式中生效, json中配置优先级高于路径中配置, 如"conf:{'system':{'config':'/var/www/xxx.php'}}" 'config' => '', //健康检查网址, 可用于初始化, 约10s一次(如: http://127.0.0.1:8888/include/of/index.php), 默认"" 'health' => '', //路由规则, 格式不含GET的路径后再与GET合并, 参考preg_replace前两参数, 如: {"@^(/[^/]+)/.*$@" : "$1.php?a=1", ...} 'routes' => array(), //自定义初始化列表, 会在每个协程加载框架完成时执行, [框架回调结构, ...] 'reinit' => array(), //自定义常量 'define' => array( //系统根路径, 默认为swoole.php所在的目录 'ROOT_DIR' => __DIR__, //框架根路径 'OF_DIR' => __DIR__ . '/include/of', ) ), //服务配置 'server' => array( //启动协程化(无法修改) 'enable_coroutine' => true, //安全重启最大等待时间(s), 超时强杀 'max_wait_time' => 86400, //协程函数范围, 默认全覆盖, 选项参考 'hook_flags' => SWOOLE_HOOK_ALL | SWOOLE_HOOK_CURL, //服务启动进程数, 默认CPU核数, 框架限制每个进程同时处理1000个请求 'worker_num' => swoole_cpu_num(), //错误日志记录等级 'log_level' => SWOOLE_LOG_WARNING, //协程抢占式调度, 默认false关闭, 若为true对密集运算的协程更友好(需更多CPU资源) 'enable_preemptive_scheduler' => false, //最大数据包 'package_max_length' => ini_get('post_max_size')的字节数, //更多参考TCP/UDP与HTTP配置 ... ), //替代PHP配置, 如max_execution_time在cli模式下永远是0, 因此设置到这里 'phpIni' => array( //请求响应超时时间, 默认30s, 等同set_time_limit(30), 此值为包含网络等操作的实际执行时间 'max_execution_time' => 30, //协程静态变量最大内存空间 'memory_limit' => ini_get('memory_limit'), //日期时间函数使用的默认时区 'date.timezone' => date_default_timezone_get() ) );
单个请求的效率提升基本无感知, 甚至可能因为过多协程的调度导致执行速度更慢 每个Swoole进程可同时响应多个请求(框架限制为1000), Ngnix与其相比需要启动更多php进程 Swoole支持的通信协议与并发任务是切实改变开发思维的壮举, 当然这些也需要资源的加持
php官网说明如下 set_time_limit()函数和配置指令max_execution_time只影响脚本本身执行的时间。 任何发生在诸如使用system()的系统调用,流操作,数据库操作等脚本的执行时间不包括其中。 在Windows上为实际执行时间。Swoole与Windows行为一致, 默认情况下是无需设置的 1. 计划任务永不超时 2. 消息队列每条是2小时超时, 超过分秒级应该改造队列 3. 网络请求若调整执行时间, 应设置在ctrl层或入口文件
可以通过两种方式优化 1. 调整启动配置 phpIni.max_execution_time 的默认值 2. 通过 set_time_limit(int) 或 ini_set('max_execution_time', int) 动态设置
<?php //全局的, 无参数 => 正常运行 class::init(); //全局的, 无参数 => 正常运行 class::_init(); //非全局(在方法或类中), 有参数 => 正常运行 function () {class::init(1);} //全局的, 有参数 => 运行报错 class::init(1); //全局的, 无参数 => 正常运行, 但不正确, 每次请求都不会判断而执行init, 应把条件放在init中 if (true) {class::init();} //同时也意味着其它初始化作用的方法名无效 => 无法每次运行, 这类情况可配置reinit参数 class::abcd();
<?php //安装SIGTERM信号处理器 pcntl_signal(15, function ($signo) {}) : //恢复linux进程对SIGTERM信号处理 pcntl_signal(15, SIG_DFL); //检查信号 pcntl_signal_dispatch();
-
namestring数据名称
-
dataarray初始数据, 默认空数组
<?php //引用返回, 多协程初始化数据 $data = &swoole::data('test', array('init' => 0)); //多协程初始化动作(无锁方式实现) ++$data['init'] === 1 ? 初始化动作 : $data['init'] = 1;
-
callcallback符合框架回调结构, 包含协程逻辑, 可以是匿名函数
-
modeint
协程模式 1=工作协程, 启动快, 可共享变量, 过多影响调度速度, 适合跨协程操作的任务 2=独立进程, 启动慢, 支持更多"工作协程", 适合运行长时间的任务 4=共享进程, 启动快, 支持少量"工作协程", 适合运行短时间的任务
-
dataarray
mode为1时生效 { "space" :&当协程运行时被设置为协程ID, 引用传值, 默认无引用 "requ" : 指定请求信息, 符合Swoole\Http\Request属性的对象, 默认父协程的请求信息 "argv" : 指定call的触发参数, 参考of::callFunc, 默认无参数 }
<?php /** 运行的协程在收到SIGTERM信号后 1. 定时器会立刻退出 2. SIG_DFL默认处理方式的go协程会等到sleep时退出 3. 其它处理方式会在调用pcntl_signal_dispatch时安全退出 */ swoole::fork(array( //符合框架的回调结构 'asCall' => $call, 'params' => array($data) ));//模拟一个含两个必要属性的requ对象, 还可以添加get post等参数 $requ = new stdClass; $requ->server = array( 'path_info' => '/index.php', 'remote_addr' => $serv->getClientInfo($fd)['remote_ip'] ); //指定请求信息回调演示 swoole::fork($call, 1, array( 'requ' => $requ ));
1. 兼容原开发方式, 部署同Apache和Ngnix相同, 启动Swoole后便可应用 2. 建议Swoole仅作为应用服务器, 用Ngnix做代理, 转发动态的php请求
1. WebSocket连接时先加载入口文件, 需返回至少包含"info"的回调数组, {"init" : 初始回调, "info" : 信息回调, "done" : 结束回调} 2. 回调符合框架回调结构, 每个回调触发时接受一个数组参数, 结构如下 init({"link" : 连接ID, "resp" : 响应对象}) info({"link" : 连接ID, "resp" : 响应对象, "info" : 信息对象}) done({"link" : 连接ID}) 3. 响应对象包含两个方法 push(string | array | 信息对象 $data) 推送信息, 数组参数转会为json, 成功返回true, 失败返回false close() 发送关闭帧并关闭连接, 成功返回true, 失败返回false 4. 支持文本ping pong帧处理, 受open_websocket_ping_frame或open_websocket_pong_frame参数影响, 自动响应数据 {"ping" : "pong", "Ping" : "Pong", "PING" : "PONG"}
<?php /** info是必须的, 否则会直接关闭连接, init和done是可选的 假设文件路径 /test.php, 先进行登录验证等操作 */ return array( //连接成功回调 'init' => function ($params) { $params['resp']->push(print_r($params, true)); }, //接受信息回调 'info' => function ($params) { //发送信息 $params['resp']->push(print_r($params, true)); //关闭连接 $params['resp']->close(); } ); ?><script> //创建连接, 注意端口 var websocket = new WebSocket('ws://127.0.0.1:8888/test.php'); //连接成功回调 websocket.onopen = function (evt) { console.log("Connected to WebSocket server."); //连接成功后发送信息 websocket.send('hello'); }; //接受信息回调 websocket.onmessage = function (evt) { console.log('Retrieved data from server: ' + evt.data); }; //关闭连接回调 websocket.onclose = function (evt) { console.log("Disconnected"); }; //出现错误回调 websocket.onerror = function (evt, e) { console.log('Error occured: ' + evt.data); }; </script>
1. 自定义服务完整的Swoole服务代码写在独立的文件中并返回服务对象, 如: /var/www/html/demo.php 2. 服务代码中调用$GLOBALS中的"system server phpIni"分别对应配置文件中的数据, 键名可扩展 3. 可以调用swoole类的私有方法和属性, 如: self::request($requ, null); 4. 参考swoole.php中"webSocket"方法的代码能更容易实现大部分自定义服务的逻辑 5. 通过命令行启动自定义服务, 如: php swoole.php "open:/var/www/html/demo.php"
<?php /** 演示http服务 假设文件路径 /var/www/html/demo.php */ $serv = new Swoole\Http\Server('0.0.0.0', $GLOBALS['system']['port'], SWOOLE_PROCESS); //请求回调 $serv->on('request', function ($requ, $resp) { //调用私有方法, 处理请求信息 self::request($requ, $resp); }); //返回服务 return $serv;############################################################################################################## ########服务开发的具体实现思路总体分五步, 客户端连接执行前三步, 接到消息执行第四步, 关闭连接执行第五步######## ############################################################################################################## //第一步拼接一个requ请求对象, 如: $requ = new stdClass; $requ->server = array( //入口文件 'path_info' => '/index.php', //客户端IP 'remote_addr' => $serv->getClientInfo($fd)['remote_ip'] );
//第二步调用swoole::request加载入口文件并保存入口文件返回的回调函数, 如: $call = self::request($requ, null);
//第三步封装一个响应对象, 为应用层提供交互功能, 并把上述数据保存到静态变量中, 如: $resp = new stdClass;
//第四步在接到客户端消息时, 通过指定请求信息和触发参数的方式创建协程回调, 如: self::fork($call, 1, array( //指定请求头 'requ' => $requ, //触发参数, 内容自定义, 如: {"link" : 连接标识, "resp" : 响应对象, "info" : 客户消息} 'argv' => array('link' => $frame->fd, 'resp' => $resp, 'info' => $frame) ));
//第五步在关闭连接时清理连接标识对应的数据, 如: unset($requ, $call, $resp);
手册地址 http://phpof.net/
- 入门指引
-
疑难解答
- 部署时会遇到的那些常见问题
简单却容易忽视 - 框架内置有哪些管理界面
生产模式进入界面需用 __OF_DEBUG__ - 如何定制不同的架构模式
通过配置入口文件中调度方法的参数即可 - 如何面向命名空间开发
of_xx 类可以按照命名空间方式调用 - 如何设置不同的部署模式
通过_of.debug设置 开发,测试,生产 模式 - 为什么控制层类文件要返回true
这是防止非法访问的方法之一 - 为什么传到视图层的变量会被编码
这是因为 XSS 安全防范的原因 - 为什么框架没有SQL构造器
因常规方案牺牲了性能又未很好解决问题 - 如何快速开发用户及权限管理功能
单点登录(SSO)模块因此而存在 - 怎么在系统的基础上扩展底层功能
三点: 扩展开发, 预先加载, 底层钩子 - 怎么使用 Composer 依赖管理工具
框架已集成, 默认关闭状态
- 部署时会遇到的那些常见问题
- 组件使用
- 集成插件
- 扩展开发
- 开发手册