_遵守規則可以讓你遠離選擇煩惱,無論是在坐車還是參加雞尾酒會的時候。 --《選擇的悖論》_
##寫在前面的話
此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文件的解析,所以在對項目代碼(包括配置)修改后,需要重啟服務,方能生效。
- 歡迎使用PhalApi!
- 接口,從簡單開始!
- [1.1]-下載與安裝
- [1.2]-創建一個自己的項目
- [1.3]-在線體驗
- [1.4]-文檔、幫助和官網
- [1.10]-對PhalApi框架的抉擇
- [1.11]-快速入門(backup)
- [1.12]-參數規則:接口參數規則配置
- [1.13]-統一的接口請求方式:_sevice=XXX.XXX
- [1.14]-統一的返回格式和結構:ret-data-msg
- [1.15]-數據庫操作:基于NotORM的使用及優化
- [1.16]-配置讀取:內外網環境配置的完美切換
- [1.17]-日記紀錄:簡化版的日記接口
- [1.18]-快速函數:人性化的關懷
- [1.19]-DI服務速查:各資源服務一覽表
- [1.20]-DB操作:數據庫基本操作速查
- [1.21]-類的自動加載:遵循PEAR包的命名規范
- [1.22]-簽名驗證:自定義簽名規則
- [1.23]-請求和響應:GET和POST兩者皆可得及超越JSON格式返回
- [1.24]-緩存策略:更靈活地可配置化的多級緩存
- [1.25]-國際化翻譯:為走向國際化提前做好翻譯準備
- [1.26]-數據安全:數據對稱加密方案
- [1.27]-精益開發:更富表現力的Model層和重量級數據獲取的應對方案
- [1.28]-COOKIE:對COOKIE原生態的支持及記憶加密升級版
- [1.29]-開放與封閉:多入口和統一初始化
- [1.30]-保持的力量:接口開發最佳實踐
- [1.31]-新型計劃任務:以接口形式實現的計劃任務
- [2.11]-核心思想:DI依賴注入-讓資源更可控
- [2.12]-海量數據:可配置的分庫分表
- [2.13]-接口調試:在線SQL語句查看與性能優化
- [2.14]-測試驅動開發:意圖導向編程下的接口開發
- [2.15]-演進:新型計劃任務續篇
- [2.16]-領域驅動設計:應對復雜領域業務的Domain層
- [2.17]-微服務:Api接口服務層
- [2.18]-定制化:資源服務的再實現
- [2.19]-擴展庫:可重用的擴展類庫
- [2.20]-約定編程:架構明顯的編程風格
- [2.21]-服務器統一部署方案簡明版:CentOs---Nginx---php-fpm---MySql-[--Memcached]
- [2.22]-更多工具:精益項目和團隊建設
- [3.1]-擴展類庫:微信開發
- [3.2]-擴展類庫:代理模式下phprpc協議的輕松支持
- [3.3]-擴展類庫:基于PHPMailer的郵件發送
- [3.4]-擴展類庫:優酷開放平臺接口調用
- [3.5]-擴展類庫:七牛云存儲接口調用
- [3.6]-擴展類庫:新型計劃任務
- [3.8]-擴展類庫:用戶、會話和第三方登錄集成
- [3.9]-擴展類庫:swoole支持下的長鏈接和異步任務實現
- [3.11]-擴展類庫:基于FastRoute的快速路由
- [4.2]-開發實戰2:模擬優酷開放平臺接口項目開發
- [4.3]-開發實戰3:一個簡單的小型項目開發(奔跑吧兄弟投票活動)
- [5.1]-架構與思想:PhalApi核心設計和思想解讀
- [5.2]-雜談:扯一些PhalApi的前世和今生
- [5.3]-框架總結:術語表和PHP開發建議
- [5.4]-許可
- [5.5]-聯系和加入我們
- [5.6]-更新日記
- [5.8]-致框架貢獻者:加入PhalApi開源指南
- [6.1]-基于接口查詢語言的SDK包
- [6.2]-SDK包(JAVA版)
- [6.3]-SDK包(PHP版)
- [6.4]-SDK包(Objective-C版)
- [6.5]-SDK包(javascript版)
- [6.6]-SDK包(Ruby版)
- [8.1]-PhalApi視頻教程
- 附錄1:接口文檔參考模板