ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
_遵守规则可以让你远离选择烦恼,无论是在坐车还是参加鸡尾酒会的时候。 --《选择的悖论》_ ##写在前面的话 此PhalApi扩展类库只是初步开发完成,建议有swoole扩展经验或非保守派的同学使用,也欢迎你来丰富完善此扩展类库。 ##3.9.1 扩展类库:swoole支持下的长链接和异步任务实现 swoole官网请见: [Swoole: PHP的异步、并行、分布式扩展](http://www.swoole.com/) 在这里,首先需要非常感谢swoole。 因为Swoole给我们提供了很多解决以往因PHP本身限制而产生的难题的灵感,但与此同时,也给我们带来了从没遇到过的挑战,特别是并发和长时间运行。 这需要我们更为小心地进行编码,因为以往可以忽略的小问题,在新的解决方案背景下都可能成为一个大问题。此扩展类库更多是作为一种尝试,并且可以作为扩展类库重要的一个转换点。因为在今后的日子里, **PhalApi将会争取与其他开源项目一起,提供企业级的解决方案** 。 目前,此扩展类库提供了: + 长链接的接口调用 + 异步计划任务的调用 ##3.9.2 安装 (1)安装swoole扩展类库 安装过程可以参考swoole官网,这里稍以linux系统简单说明一下编译安装。 ```javascript unzip ./swoole-src-swoole-1.7.16-beta.zip cd swoole-src-swoole-1.7.16-beta phpize ./configure make && make install ``` 安装好后,添加swoole扩展: ```javascript extension=swoole.so ``` 重启PHP后,如果看到有swoole扩展,则说明安装成功: ```javascript #php -m | grep swoole swoole ``` ###(2)扩展包下载 从 [PhalApi-Library](http://git.oschina.net/dogstar/PhalApi-Library) 扩展库中下载获取 **Swoole** 包,如使用: ```javascript git clone https://git.oschina.net/dogstar/PhalApi-Library.git ``` 然后把 **Swoole** 目录复制到 **./PhalApi/Library/** 下,即: ```javascript cp ./PhalApi-Library/Swoole/ ./PhalApi/Library/ -R ``` 到此安装完毕! > 温馨提示: > 此扩展类库需要PhaApi 1.1.4及以上版本。 ###(3)配置 将以下配置追加到./Config/app.php: ```javascript /** * Swoole扩展类库 */ 'Swoole' => array( //服务 'server' => array( 'ip' => '127.0.0.1', 'port' => 9501, 'worker_num' => 1, ), //计划任务 'task' => array( 'ip' => '127.0.0.1', 'port' => 9502, 'worker_num' => 1, ), ), ``` ##3.9.3 入门使用 ###(1)长链接入口 在使用长链接入口对外提供接口服务后,由于不再是HTTP协议,所以入口建议放置在新的目录./Server,而不再是./Public。 入口文件的编写,如同我们以往一样,很简单: ```javascript //$ vim ./Server/run_server.php <?php require_once dirname(__FILE__) . '/../Public/init.php'; DI()->loader->addDirs(array('Library', 'Demo')); $swooleLite = new Swoole_Lite(); $swooleLite->runServer(); ``` ####启动、重启和关闭服务 启动可以用: ```javascript php ./Server/run_server.php ``` 关闭可以用: ```javascript ps -ef | grep run_server | grep -v grep | awk '{print $2}'|xargs kill -9 ``` ###(2)异步计划任务 异步计划任务是新型的做法,即:也通过接口服务调用的方式来完成计划任务的调度,其启动文件如同长链接入口一样简单: ```javascript //$ vim ./Server/run_task.php <?php require_once dirname(__FILE__) . '/../Public/init.php'; DI()->loader->addDirs(array('Library', 'Demo')); $swooleLite = new Swoole_Lite(); $swooleLite->runTask(); ``` ####启动、重启和关闭服务 启动可以用: ```javascript nohup php ./Server/run_task.php > ./Server/run_task.log 2>&1 & ``` ###(3)客户端调用 在扩展类库里有一个测试的脚本,可以用来进行PHP客户端的请求。 ####(1)默认接口调用 ```javascript $ php ./check.php 127.0.0.1 9501 Default.Index username=swoole Send: {"service":"Default.Index","username":"swoole"} Received: {"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430620911},"msg":""} Connection close ``` ####(2)带数据库的调用 ```javascript $ php ./check.php 127.0.0.1 9501 User.getBaseInfo userId=1 Send: {"service":"User.getBaseInfo","userId":"1"} Received: {"ret":200,"data":{"code":0,"msg":"","info":{"id":"1","username":"aevit","nickname":"test","password":"DE4CA99150F44B26F0D320DCA6E4B7629C43B6","salt":"wefewfew","reg_time":"0","avatar":"http:\/\/image.famillelab.com\/no_avatar.png","UUID":""}},"msg":""} Connection close ``` ####(3)异步计划任务的调度 ```javascript $ php ./check.php 127.0.0.1 9502 Default.Index username=swoole Send: {"service":"Default.Index","username":"swoole"} Connection close ``` 假设Default.Index为一个计划任务的接口,但目前发现一个问题是,首次请求异步计划任务不会主动结束,而需要工作强制ctrl + c结束,再请求,则正常。 对应的log,可以看到: ```javascript 2015-05-03 12:24:57|DEBUG|asynctask(0) dispath in swoole|{"service":"Default.Index","username":"swoole"} 2015-05-03 12:24:57|DEBUG|asynctask(0) start in swoole|{"service":"Default.Index","username":"swoole"} 2015-05-03 12:24:57|DEBUG|asynctask(0) finish in swoole|{"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430627097},"msg":""} 2015-05-03 12:24:57|DEBUG|asynctask(1) dispath in swoole|{"service":"Default.Index","username":"swoole"} 2015-05-03 12:24:57|DEBUG|asynctask(1) start in swoole|{"service":"Default.Index","username":"swoole"} 2015-05-03 12:24:57|DEBUG|asynctask(1) finish in swoole|{"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430627097},"msg":""} ... ``` ##3.9.4 对客户端调整 ###(1)调用方式的改变 改用长链接。 ###(2)POST参数传递方式的改变 统一使用json发送数据包。 ##3.9.5 对服务端的影响 ###(1)DI资源服务的调整 变量名称|是否全局通用|是否每次请求新建|可否使用|备注 ---|---|---|---|--- loader|是|否|可使用| config|是|否|可使用| logger|是|否|可使用| notorm|是|否|可使用|每次响应后,关闭此次全部数据库链接 cache|是|否|可使用|需要查看使用的链接是否支持长链接 filter|是|否|可使用| crypt|是|否|可使用| curl|是|否|可使用| request|否|是|可使用| response|否|是|可使用| cookie|---|---|不可使用|长链接下不应进行COOKIE的操作 ###(2)关于swoole扩展类库的自问自答 + 1、数据库使用长链接吗? -- 不使用,每次响应后手动关闭数据链接 + 2、内存问题?-- 通过类成员方法的作用域控制内存 + 3、并发的问题?-- TODO + 4、代码更新后如何同步?需要重启服务器吗? -- 需要重启 + 5、PhalApi_Response::formatResult()的访问权限,是框架的调整,还是个别自我提高? -- 扩展自我提高 + 6、注册错误回调函数? -- 来自swoole的建议,已注册 + 7、启动和关闭、重启脚本文件? -- 提供参考命令 + 8、一直运行? -- TODO ###(3)特别注意! 由于服务在启动后,已经完成了大部分的类加载、配置读取以及PHP文件的解析,所以在对项目代码(包括配置)修改后,需要重启服务,方能生效。