diff --git a/README.md b/README.md
index 8b99771..37d9e37 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- Server
- Client
- Coroutine
-- AsyncIO
+- Async
- Memory
- Process
- HttpServer
@@ -68,61 +68,69 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`1.4.4`** stat缓存清理
- **`1.4.5`** mt_rand随机数
- #### **1.5** 版本更新记录
- - **`1.5.1`** 4.0.4
- - **`1.5.2`** 4.0.2
- - **`1.5.3`** 4.0.3
- - **`1.5.4`** 4.0.1
- - **`1.5.5`** 4.0.0
- - #### **1.6** 新特性使用
- - **`1.6.1`** 2.1.2 进程池模块的使用
- - **`1.6.2`** 1.9.24 调度支持 Stream 模式
- - **`1.6.3`** 1.9.24 异步客户端自动解析域名
- - **`1.6.4`** 1.9.17 支持异步安全重启特性
- - **`1.6.5`** 1.9.14 使用异步客户端超时机制
- - **`1.6.6`** 1.8.0 使用内置Http异步客户端
- - **`1.6.7`** 1.7.16 使用迭代器遍历Server所有连接
- - **`1.6.8`** 1.7.5 在Server中使用swoole_table
- - **`1.6.9`** 1.7.5 swoole_client支持sendfile接口
- - **`1.6.10`** 1.7.4 SSL隧道加密TCP-Server
- - **`1.6.11`** 1.7.4 task进程中使用毫秒定时器
- - **`1.6.12`** 1.7.3 固定包头+包体协议自动分包
- - **`1.6.13`** 1.7.3 onTask直接return取代finish函数
- - **`1.6.14`** 1.7.2 swoole_process多进程模块的使用
- - **`1.6.15`** 1.7.2 task进程使用消息队列
- - #### **1.7** 项目路线图
- - #### **1.8** php.ini选项
- - #### **1.9** 内核参数调整
- - #### **1.11** 衍生开源项目
- - **`1.11.1`** 框架
- - **`1.11.2`** 工具
- - **`1.11.3`** 分布式
- - **`1.11.4`** 通信协议
- - #### **1.12** 用户与案例
- - **`1.12.1`** 物联网项目
- - **`1.12.2`** 网络游戏
- - **`1.12.3`** 腾讯(Tencent)
- - **`1.12.4`** 百度(Baidu.com)
- - **`1.12.5`** 阅文集团
- - **`1.12.6`** BiliBili(哔哩哔哩)
- - **`1.12.7`** 车轮互联(chelun.com)
- - **`1.12.8`** (捞月狗) 游戏社区
- - #### **1.13** 提交错误报告
- - #### **1.14** 常见问题
- - **`1.14.1`** 升级swoole版本的常见问题
- - **`1.14.2`** 生成可分发的二进制swoole版本
- - **`1.14.3`** 在phpinfo中有在php-m中没有
- - **`1.14.4`** Connection refused是怎么回事
- - **`1.14.5`** Resource temporarily unavailable [11]
- - **`1.14.6`** Cannot assign requested address [99]
- - **`1.14.7`** swoole与node.js相比有哪些优势
- - **`1.14.8`** swoole与golang相比有哪些优势
- - **`1.14.9`** pcre.h: No such file or directory
- - **`1.14.10`** my_global.h: No such file or directory
- - **`1.14.11`** undefined symbol: __sync_bool_compare_and_swap_4
- - **`1.14.12`** 学习Swoole需要掌握哪些基础知识
- - **`1.14.13`** 同步阻塞与异步非阻塞适用场景
- - **`1.14.14`** PHP7环境下出现zend_mm_heap corrupted
- - **`1.14.15`** swoole项目起源和名字由来
+ - **`1.5.1`** 4.2.2
+ - **`1.5.2`** 4.2.1
+ - **`1.5.3`** 4.2.0
+ - **`1.5.4`** 4.1.2
+ - **`1.5.5`** 4.1.1
+ - **`1.5.6`** 4.1.0
+ - **`1.5.7`** 4.0.4
+ - **`1.5.8`** 4.0.3
+ - **`1.5.9`** 4.0.2
+ - **`1.5.10`** 4.0.1
+ - **`1.5.11`** 4.0.0
+ - #### **1.6** 向下不兼容改动
+ - #### **1.7** 新特性使用
+ - **`1.7.1`** 2.1.2 进程池模块的使用
+ - **`1.7.2`** 1.9.24 调度支持 Stream 模式
+ - **`1.7.3`** 1.9.24 异步客户端自动解析域名
+ - **`1.7.4`** 1.9.17 支持异步安全重启特性
+ - **`1.7.5`** 1.9.14 使用异步客户端超时机制
+ - **`1.7.6`** 1.8.0 使用内置Http异步客户端
+ - **`1.7.7`** 1.7.16 使用迭代器遍历Server所有连接
+ - **`1.7.8`** 1.7.5 在Server中使用swoole_table
+ - **`1.7.9`** 1.7.5 swoole_client支持sendfile接口
+ - **`1.7.10`** 1.7.4 SSL隧道加密TCP-Server
+ - **`1.7.11`** 1.7.4 task进程中使用毫秒定时器
+ - **`1.7.12`** 1.7.3 固定包头+包体协议自动分包
+ - **`1.7.13`** 1.7.3 onTask直接return取代finish函数
+ - **`1.7.14`** 1.7.2 swoole_process多进程模块的使用
+ - **`1.7.15`** 1.7.2 task进程使用消息队列
+ - #### **1.8** 项目路线图
+ - #### **1.9** php.ini选项
+ - #### **1.10** 内核参数调整
+ - #### **1.12** 衍生开源项目
+ - **`1.12.1`** 框架
+ - **`1.12.2`** 工具
+ - **`1.12.3`** 分布式
+ - **`1.12.4`** 通信协议
+ - #### **1.13** 用户与案例
+ - **`1.13.1`** 物联网项目
+ - **`1.13.2`** 网络游戏
+ - **`1.13.3`** 腾讯(Tencent)
+ - **`1.13.4`** 百度(Baidu.com)
+ - **`1.13.5`** 阅文集团
+ - **`1.13.6`** BiliBili(哔哩哔哩)
+ - **`1.13.7`** 车轮互联(chelun.com)
+ - **`1.13.8`** (捞月狗) 游戏社区
+ - #### **1.14** 提交错误报告
+ - #### **1.15** 常见问题
+ - **`1.15.1`** 升级swoole版本的常见问题
+ - **`1.15.2`** 生成可分发的二进制swoole版本
+ - **`1.15.3`** 在phpinfo中有在php -m中没有
+ - **`1.15.4`** Connection refused是怎么回事
+ - **`1.15.5`** Resource temporarily unavailable [11]
+ - **`1.15.6`** Cannot assign requested address [99]
+ - **`1.15.7`** swoole与node.js相比有哪些优势
+ - **`1.15.8`** swoole与golang相比有哪些优势
+ - **`1.15.9`** pcre.h: No such file or directory
+ - **`1.15.10`** my_global.h: No such file or directory
+ - **`1.15.11`** undefined symbol: __sync_bool_compare_and_swap_4
+ - **`1.15.12`** 学习Swoole需要掌握哪些基础知识
+ - **`1.15.13`** 同步阻塞与异步非阻塞适用场景
+ - **`1.15.14`** PHP7环境下出现zend_mm_heap corrupted
+ - **`1.15.15`** swoole项目起源和名字由来
+ - **`1.15.16`** swFactoryProcess_finish (ERROR 1004): send %d byte failed, because session#%d is closed / swFactoryProcess_finish (ERROR 1005): connection[fd=%d] does not exists
- ### **2** Server
- #### **2.1** 函数列表
- **`2.1.1`** swoole_server::__construct
@@ -218,11 +226,12 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`2.3.44`** open_http2_protocol
- **`2.3.45`** open_websocket_protocol
- **`2.3.46`** open_mqtt_protocol
- - **`2.3.47`** reload_async
- - **`2.3.48`** tcp_fastopen
- - **`2.3.49`** request_slowlog_file
- - **`2.3.50`** enable_coroutine
- - **`2.3.51`** max_coroutine
+ - **`2.3.47`** open_websocket_close_frame
+ - **`2.3.48`** reload_async
+ - **`2.3.49`** tcp_fastopen
+ - **`2.3.50`** request_slowlog_file
+ - **`2.3.51`** enable_coroutine
+ - **`2.3.52`** max_coroutine
- #### **2.4** 监听端口
- **`2.4.1`** 可选参数
- **`2.4.2`** 可选回调
@@ -272,6 +281,7 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- #### **2.9** 压力测试
- **`2.9.1`** 并发10万TCP连接的测试
- **`2.9.2`** PHP7+Swoole/Nginx/Golang性能对比
+ - **`2.9.3`** 全球Web框架权威性能测试 Techempower Web Framework Benchmarks
- ### **3** Client
- #### **3.1** 方法列表
- **`3.1.1`** swoole_client::__construct
@@ -330,18 +340,19 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`4.1.12`** Coroutine::readFile
- **`4.1.13`** Coroutine::writeFile
- **`4.1.14`** Coroutine::stats
+ - **`4.1.15`** Coroutine::getBackTrace
+ - **`4.1.16`** Coroutine::listCoroutines
- #### **4.2** Coroutine\Channel
- **`4.2.1`** Coroutine\Channel->__construct
- **`4.2.2`** Coroutine\Channel->push
- **`4.2.3`** Coroutine\Channel->pop
- **`4.2.4`** Coroutine\Channel->stats
- **`4.2.5`** Coroutine\Channel->close
- - **`4.2.6`** Coroutine\Channel::select
- - **`4.2.7`** Coroutine\Channel->length
- - **`4.2.8`** Coroutine\Channel->isEmpty
- - **`4.2.9`** Coroutine\Channel->isFull
- - **`4.2.10`** Coroutine\Channel->$capacity
- - **`4.2.11`** Coroutine\Channel->$errCode
+ - **`4.2.6`** Coroutine\Channel->length
+ - **`4.2.7`** Coroutine\Channel->isEmpty
+ - **`4.2.8`** Coroutine\Channel->isFull
+ - **`4.2.9`** Coroutine\Channel->$capacity
+ - **`4.2.10`** Coroutine\Channel->$errCode
- #### **4.3** Coroutine\Client
- **`4.3.1`** Coroutine\Client->connect
- **`4.3.2`** Coroutine\Client->send
@@ -356,7 +367,8 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`4.4.5`** Coroutine\Http\Client->push
- **`4.4.6`** Coroutine\Http\Client->recv
- **`4.4.7`** Coroutine\Http\Client->addFile
- - **`4.4.8`** Coroutine\Http\Client->download
+ - **`4.4.8`** Coroutine\Http\Client->addData
+ - **`4.4.9`** Coroutine\Http\Client->download
- #### **4.5** Coroutine\Http2\Client
- **`4.5.1`** Coroutine\Http2\Client->__construct
- **`4.5.2`** Coroutine\Http2\Client->set
@@ -390,6 +402,7 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`4.8.6`** Coroutine\MySQL\Statement->fetch
- **`4.8.7`** Coroutine\MySQL\Statement->fetchAll
- **`4.8.8`** Coroutine\MySQL\Statement->nextResult
+ - **`4.8.9`** Coroutine\MySQL->execFile
- #### **4.9** Coroutine\PostgreSQL
- **`4.9.1`** Coroutine\PostgreSQL->connect
- **`4.9.2`** Coroutine\PostgreSQL->query
@@ -401,24 +414,33 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`4.9.8`** Coroutine\PostgreSQL->fetchArray
- **`4.9.9`** Coroutine\PostgreSQL->fetchRow
- **`4.9.10`** Coroutine\PostgreSQL->metaData
- - #### **4.10** Server
- - #### **4.11** 并发调用
- - **`4.11.1`** 使用实例
- - **`4.11.2`** 子协程+通道
- - #### **4.12** 实现原理
- - **`4.12.1`** 协程与线程
- - **`4.12.2`** 发送数据协程调度
- - **`4.12.3`** 协程内存开销
- - **`4.12.4`** 4.0 协程实现原理
- - #### **4.13** 常见问题
- - **`4.13.1`** 运行中出现 Fatal error: Maximum function nesting level of '1000' reached, aborting!
- - **`4.13.2`** 为什么只能在回调函数中使用协程客户端
- - **`4.13.3`** 支持协程的回调方法列表
- - #### **4.14** 编程须知
- - **`4.14.1`** 在多个协程间共用同一个协程客户端
- - **`4.14.2`** 禁止使用协程 API 的场景 (Swoole4以下版本)
- - **`4.14.3`** 使用类静态变量/全局变量保存上下文
-- ### **5** AsyncIO
+ - #### **4.10** Runtime::enableCoroutine
+ - **`4.10.1`** 文件操作
+ - **`4.10.2`** 睡眠函数
+ - **`4.10.3`** 开关选项
+ - #### **4.11** Server
+ - #### **4.12** 并发调用
+ - **`4.12.1`** Defer 机制
+ - **`4.12.2`** 子协程+通道
+ - #### **4.13** 实现原理
+ - **`4.13.1`** 协程与线程
+ - **`4.13.2`** 发送数据协程调度
+ - **`4.13.3`** 协程内存开销
+ - **`4.13.4`** 4.0 协程实现原理
+ - #### **4.14** 常见问题
+ - **`4.14.1`** 运行中出现 Fatal error: Maximum function nesting level of '1000' reached, aborting!
+ - **`4.14.2`** 为什么只能在回调函数中使用协程客户端
+ - **`4.14.3`** 支持协程的回调方法列表
+ - **`4.14.4`** 错误信息: XXXX client has already been bound to another coroutine
+ - **`4.14.5`** Swoole4 协程与 PHP 的 Yield/Generator 协程有什么区别
+ - #### **4.15** 编程须知
+ - **`4.15.1`** 在多个协程间共用同一个协程客户端
+ - **`4.15.2`** 禁止使用协程 API 的场景 (Swoole4以下版本)
+ - **`4.15.3`** 使用类静态变量/全局变量保存上下文
+ - #### **4.16** 退出协程
+ - #### **4.17** 扩展组件
+ - **`4.17.1`** MongoDB
+- ### **5** Async
- #### **5.1** 异步文件系统IO
- **`5.1.1`** swoole_async_readfile
- **`5.1.2`** swoole_async_writefile
@@ -442,7 +464,7 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`5.3.2`** swoole_timer_after
- **`5.3.3`** swoole_timer_clear
- #### **5.4** 异步MySQL客户端
- - **`5.4.1`** swoole_mysql->construct
+ - **`5.4.1`** swoole_mysql->__construct
- **`5.4.2`** swoole_mysql->on
- **`5.4.3`** swoole_mysql->connect
- **`5.4.4`** swoole_mysql->escape
@@ -577,6 +599,7 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`8.4.1`** upload_tmp_dir
- **`8.4.2`** http_parse_post
- **`8.4.3`** document_root
+ - **`8.4.4`** http_compression
- #### **8.5** 常见问题
- **`8.5.1`** CURL发送POST请求服务器端超时
- **`8.5.2`** 使用Chrome访问服务器会产生2次请求
@@ -595,12 +618,14 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- #### **9.3** 预定义常量
- #### **9.4** 常见问题
- #### **9.5** 配置选项
+ - #### **9.6** swoole_websocket_frame
- ### **10** Process\Pool
- #### **10.1** Process\Pool::__construct
- #### **10.2** Process\Pool->on
- #### **10.3** Process\Pool->listen
- #### **10.4** Process\Pool->write
- #### **10.5** Process\Pool->start
+ - #### **10.6** Process\Pool->getProcess
- ### **11** Redis\Server
- #### **11.1** 方法
- **`11.1.1`** setHandler
@@ -632,6 +657,7 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- #### **12.20** 异步回调程序内存管理
- #### **12.21** 日志等级控制
- #### **12.22** 使用 asan 内存检测
+ - #### **12.23** Windows编译
- ### **13** 其他
- #### **13.1** 函数列表
- **`13.1.1`** swoole_set_process_name
@@ -642,104 +668,106 @@ Swoole是开源免费的自由软件,授权协议是`Apache2.0`。企业和个
- **`13.1.6`** swoole_clear_dns_cache
- **`13.1.7`** swoole_get_local_mac
- **`13.1.8`** swoole_cpu_num
- - #### **13.3** 捐赠Swoole项目
- - #### **13.4** 加入Swoole开发组
- - #### **13.5** 附录:Linux信号列表
- - #### **13.6** 附录:Linux错误信息(errno)列表
- - #### **13.7** 附录:TCP连接的状态
- - #### **13.8** 附录:tcpdump抓包工具的使用
- - #### **13.9** 附录:strace工具的使用
- - #### **13.10** 附录:gdb工具的使用
- - #### **13.11** 附录:lsof工具的使用
- - #### **13.12** 附录:perf工具的使用
- - #### **13.13** 附录:编译PHP扩展的相关工具
- - #### **13.14** 备用:已移除的历史特性
- - **`13.14.1`** swoole_server->handler
- - **`13.14.2`** task_worker_max
- - **`13.14.3`** swoole_server->addtimer
- - **`13.14.4`** swoole_server->deltimer
- - **`13.14.5`** onTimer
- - **`13.14.6`** swoole_timer_add
- - **`13.14.7`** swoole_timer_del
- - **`13.14.8`** swoole_get_mysqli_sock
- - **`13.14.9`** swoole_mysql_query
- - **`13.14.10`** onMasterConnect
- - **`13.14.11`** onMasterClose
- - **`13.14.12`** Nginx/Golang/Swoole/Node.js的性能对比
- - **`13.14.13`** Coroutine::call_user_func
- - **`13.14.14`** Coroutine::call_user_func_array
- - #### **13.15** 历史:版本更新记录(1.x)
- - **`13.15.1`** 1.10.3
- - **`13.15.2`** 1.10.2
- - **`13.15.3`** 1.10.1
- - **`13.15.4`** 1.10.0
- - **`13.15.5`** 1.9.23
- - **`13.15.6`** 1.9.22
- - **`13.15.7`** 1.9.19
- - **`13.15.8`** 1.9.18
- - **`13.15.9`** 1.9.17
- - **`13.15.10`** 1.9.16
- - **`13.15.11`** 1.9.15
- - **`13.15.12`** 1.9.14
- - **`13.15.13`** 1.9.12
- - **`13.15.14`** 1.9.11
- - **`13.15.15`** 1.9.9
- - **`13.15.16`** 1.9.7
- - **`13.15.17`** 1.9.6
- - **`13.15.18`** 1.9.5
- - **`13.15.19`** 1.9.4
- - **`13.15.20`** 1.9.3
- - **`13.15.21`** 1.9.2
- - **`13.15.22`** 1.9.1
- - **`13.15.23`** 1.9.0
- - **`13.15.24`** 1.8.13
- - **`13.15.25`** 1.8.12
- - **`13.15.26`** 1.8.11
- - **`13.15.27`** 1.8.10
- - **`13.15.28`** 1.8.9
- - **`13.15.29`** 1.8.8
- - **`13.15.30`** 1.8.7
- - **`13.15.31`** 1.8.6
- - **`13.15.32`** 1.8.5
- - **`13.15.33`** 1.8.4
- - **`13.15.34`** 1.8.3
- - **`13.15.35`** 1.8.2
- - **`13.15.36`** 1.8.1
- - **`13.15.37`** 1.8.0
- - **`13.15.38`** 1.7.22
- - **`13.15.39`** 1.7.21
- - **`13.15.40`** 1.7.20
- - **`13.15.41`** 1.7.19
- - **`13.15.42`** 1.7.18
- - **`13.15.43`** 1.7.17
- - **`13.15.44`** 1.7.16
- - **`13.15.45`** 1.7.15
- - **`13.15.46`** 1.7.14
- - **`13.15.47`** 1.7.13
- - **`13.15.48`** 1.7.12
- - **`13.15.49`** 1.7.11
- - **`13.15.50`** 1.7.10
- - **`13.15.51`** 1.7.9
- - **`13.15.52`** 1.7.8
- - **`13.15.53`** 1.7.7
- - **`13.15.54`** 1.7.6
- - **`13.15.55`** 1.7.5
- - **`13.15.56`** v1.5
- - **`13.15.57`** v1.6
- - **`13.15.58`** v1.7
- - #### **13.16** 历史:版本更新记录(2.x)
- - **`13.16.1`** 2.0.1-Alpha
- - **`13.16.2`** 2.0.5
- - **`13.16.3`** 2.0.9
- - **`13.16.4`** 1.9.21
- - **`13.16.5`** 2.0.10
- - **`13.16.6`** 2.0.11
- - **`13.16.7`** 2.0.12
- - **`13.16.8`** 2.0.13
- - **`13.16.9`** 2.1.1
- - **`13.16.10`** 2.1.2
- - **`13.16.11`** 2.2.0
- - **`13.16.12`** 3.0.0
- - #### **13.19** 参与开源项目指引
+ - #### **13.3** Swoole技术会议
+ - #### **13.4** 捐赠Swoole项目
+ - #### **13.5** 加入Swoole开发组
+ - #### **13.6** 附录:Linux信号列表
+ - #### **13.7** 附录:Linux错误信息(errno)列表
+ - #### **13.8** 附录:TCP连接的状态
+ - #### **13.9** 附录:tcpdump抓包工具的使用
+ - #### **13.10** 附录:strace工具的使用
+ - #### **13.11** 附录:gdb工具的使用
+ - #### **13.12** 附录:lsof工具的使用
+ - #### **13.13** 附录:perf工具的使用
+ - #### **13.14** 附录:编译PHP扩展的相关工具
+ - #### **13.15** 备用:已移除的历史特性
+ - **`13.15.1`** swoole_server->handler
+ - **`13.15.2`** task_worker_max
+ - **`13.15.3`** swoole_server->addtimer
+ - **`13.15.4`** swoole_server->deltimer
+ - **`13.15.5`** onTimer
+ - **`13.15.6`** swoole_timer_add
+ - **`13.15.7`** swoole_timer_del
+ - **`13.15.8`** swoole_get_mysqli_sock
+ - **`13.15.9`** swoole_mysql_query
+ - **`13.15.10`** onMasterConnect
+ - **`13.15.11`** onMasterClose
+ - **`13.15.12`** Nginx/Golang/Swoole/Node.js的性能对比
+ - **`13.15.13`** Coroutine::call_user_func
+ - **`13.15.14`** Coroutine::call_user_func_array
+ - **`13.15.15`** Coroutine\Channel::select
+ - #### **13.16** 历史:版本更新记录(1.x)
+ - **`13.16.1`** 1.10.3
+ - **`13.16.2`** 1.10.2
+ - **`13.16.3`** 1.10.1
+ - **`13.16.4`** 1.10.0
+ - **`13.16.5`** 1.9.23
+ - **`13.16.6`** 1.9.22
+ - **`13.16.7`** 1.9.19
+ - **`13.16.8`** 1.9.18
+ - **`13.16.9`** 1.9.17
+ - **`13.16.10`** 1.9.16
+ - **`13.16.11`** 1.9.15
+ - **`13.16.12`** 1.9.14
+ - **`13.16.13`** 1.9.12
+ - **`13.16.14`** 1.9.11
+ - **`13.16.15`** 1.9.9
+ - **`13.16.16`** 1.9.7
+ - **`13.16.17`** 1.9.6
+ - **`13.16.18`** 1.9.5
+ - **`13.16.19`** 1.9.4
+ - **`13.16.20`** 1.9.3
+ - **`13.16.21`** 1.9.2
+ - **`13.16.22`** 1.9.1
+ - **`13.16.23`** 1.9.0
+ - **`13.16.24`** 1.8.13
+ - **`13.16.25`** 1.8.12
+ - **`13.16.26`** 1.8.11
+ - **`13.16.27`** 1.8.10
+ - **`13.16.28`** 1.8.9
+ - **`13.16.29`** 1.8.8
+ - **`13.16.30`** 1.8.7
+ - **`13.16.31`** 1.8.6
+ - **`13.16.32`** 1.8.5
+ - **`13.16.33`** 1.8.4
+ - **`13.16.34`** 1.8.3
+ - **`13.16.35`** 1.8.2
+ - **`13.16.36`** 1.8.1
+ - **`13.16.37`** 1.8.0
+ - **`13.16.38`** 1.7.22
+ - **`13.16.39`** 1.7.21
+ - **`13.16.40`** 1.7.20
+ - **`13.16.41`** 1.7.19
+ - **`13.16.42`** 1.7.18
+ - **`13.16.43`** 1.7.17
+ - **`13.16.44`** 1.7.16
+ - **`13.16.45`** 1.7.15
+ - **`13.16.46`** 1.7.14
+ - **`13.16.47`** 1.7.13
+ - **`13.16.48`** 1.7.12
+ - **`13.16.49`** 1.7.11
+ - **`13.16.50`** 1.7.10
+ - **`13.16.51`** 1.7.9
+ - **`13.16.52`** 1.7.8
+ - **`13.16.53`** 1.7.7
+ - **`13.16.54`** 1.7.6
+ - **`13.16.55`** 1.7.5
+ - **`13.16.56`** v1.5
+ - **`13.16.57`** v1.6
+ - **`13.16.58`** v1.7
+ - #### **13.17** 历史:版本更新记录(2.x)
+ - **`13.17.1`** 2.0.1-Alpha
+ - **`13.17.2`** 2.0.5
+ - **`13.17.3`** 2.0.9
+ - **`13.17.4`** 1.9.21
+ - **`13.17.5`** 2.0.10
+ - **`13.17.6`** 2.0.11
+ - **`13.17.7`** 2.0.12
+ - **`13.17.8`** 2.0.13
+ - **`13.17.9`** 2.1.1
+ - **`13.17.10`** 2.1.2
+ - **`13.17.11`** 2.2.0
+ - **`13.17.12`** 3.0.0
+ - #### **13.20** 参与开源项目指引
diff --git "a/doc/1 - \345\205\245\351\227\250\346\214\207\345\274\225.md" "b/doc/1 - \345\205\245\351\227\250\346\214\207\345\274\225.md"
index 03edd64..53a162a 100644
--- "a/doc/1 - \345\205\245\351\227\250\346\214\207\345\274\225.md"
+++ "b/doc/1 - \345\205\245\351\227\250\346\214\207\345\274\225.md"
@@ -1,32 +1,33 @@
# 入门指引
-Swoole虽然是标准的PHP扩展,实际上与普通的扩展不同。普通的扩展只是提供一个库函数。而swoole扩展在运行后会接管PHP的控制权,进入事件循环。当IO事件发生后,swoole会自动回调指定的PHP函数。
+ `Swoole`虽然是标准的PHP扩展,实际上与普通的扩展不同。普通的扩展只是提供一个库函数。而swoole扩展在运行后会接管PHP的控制权,进入事件循环。当IO事件发生后,swoole会自动回调指定的`PHP`函数。
-* 新手入门教程:[https://github.com/LinkedDestiny/swoole-doc](https://github.com/LinkedDestiny/swoole-doc)
+* 新手入门教程:[https://github.com/LinkedDestiny/swoole-doc](https://github.com/LinkedDestiny/swoole-doc) (已停更)
+* Easy Swoole (Swoole 简明指南):[https://linkeddestiny.gitbooks.io/easy-swoole/content/](https://linkeddestiny.gitbooks.io/easy-swoole/content/)
-Swoole要求使用者必须具备一定的Linux/Unix环境编程基础,[《学习Swoole需要掌握哪些基础知识》](https://wiki.swoole.com/wiki/page/487.html) 本文列出了基础知识清单。
+`Swoole`要求使用者必须具备一定的`Linux/Unix`环境编程基础,[《学习Swoole需要掌握哪些基础知识》](https://wiki.swoole.com/wiki/page/487.html) 本文列出了基础知识清单。
-swoole_server
+Server
----
-强大的TCP/UDP Server框架,多线程,EventLoop,事件驱动,异步,Worker进程组,Task异步任务,毫秒定时器,SSL/TLS隧道加密。
+强大的`TCP/UDP Server`框架,支持多线程,`EventLoop`,事件驱动,异步,`Worker`进程组,`Task`异步任务,毫秒定时器,`SSL/TLS`隧道加密。
-* `swoole_http_server`是`swoole_server`的子类,内置了Http的支持
-* `swoole_websocket_server`是`swoole_http_server`的子类,内置了WebSocket的支持
-* `swoole_redis_server`是`swoole_server`的子类,内置了Redis服务器端协议的支持
+* `swoole_http_server`是`swoole_server`的子类,内置了`Http`的支持
+* `swoole_websocket_server`是`swoole_http_server`的子类,内置了`WebSocket`的支持
+* `swoole_redis_server`是`swoole_server`的子类,内置了`Redis`服务器端协议的支持
> 子类可以调用父类的所有方法和属性
-swoole_client
+Client
-----
`TCP/UDP/UnixSocket`客户端,支持`IPv4/IPv6`,支持`SSL/TLS`隧道加密,支持`SSL`双向证书,支持同步并发调用,支持异步事件驱动编程。
-swoole_event
+Event
----
-EventLoop API,让用户可以直接操作底层的事件循环,将socket,stream,管道等Linux文件加入到事件循环中。
+`EventLoop API`,让用户可以直接操作底层的事件循环,将`socket`,`stream`,管道等`Linux`文件加入到事件循环中。
-> eventloop接口仅可用于socket类型的文件描述符,不能用于磁盘文件读写
+>`eventloop`接口仅可用于`socket`类型的文件描述符,不能用于磁盘文件读写
-swoole_async
+Async
----
异步IO接口,提供了 异步文件系统IO,定时器,异步DNS查询,异步MySQL等API,异步Http客户端,异步Redis客户端。
@@ -42,17 +43,18 @@ Swoole在2.0开始内置协程(Coroutine)的能力,提供了具备协程能力
开发者可以无感知的用同步的代码编写方式达到异步IO的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护。
同时由于swoole是在底层封装了协程,所以对比传统的php层协程框架,开发者不需要使用yield关键词来标识一个协程IO操作,所以不再需要对yield的语义进行深入理解以及对每一级的调用都修改为yield,这极大的提高了开发效率。
-swoole_process
+
+Process
----
进程管理模块,可以方便的创建子进程,进程间通信,进程管理。
-swoole_buffer
+Buffer
----
-强大的内存区管理工具,像C一样进行指针计算,又无需关心内存的申请和释放,而且不用担心内存越界,底层全部做好了。
+强大的内存区管理工具,像`C`一样进行指针计算,又无需关心内存的申请和释放,而且不用担心内存越界,底层全部做好了。
-swoole_table
+Table
-----
基于共享内存和自旋锁实现的超高性能内存表。彻底解决线程,进程间数据共享,加锁同步等问题。
-> swoole_table的性能可以达到单线程每秒读写100W次
+> `swoole_table`的性能可以达到单线程每秒读写`200W`次
diff --git "a/doc/1.1 - \347\216\257\345\242\203\344\276\235\350\265\226.md" "b/doc/1.1 - \347\216\257\345\242\203\344\276\235\350\265\226.md"
index f8db778..92eb996 100644
--- "a/doc/1.1 - \347\216\257\345\242\203\344\276\235\350\265\226.md"
+++ "b/doc/1.1 - \347\216\257\345\242\203\344\276\235\350\265\226.md"
@@ -13,7 +13,7 @@ PHP版本依赖
----------
* `Swoole-1.x`需要 `PHP-5.3.10` 或更高版本
* `Swoole-2.x`需要 `PHP-7.0.0` 或更高版本
-* `Swoole-4.x`需要 `PHP-7.0.0` 或更高版本
+* `Swoole-4.x`需要 `PHP-7.1.0` 或更高版本
* 不依赖 `PHP` 的 `stream`、`sockets`、`pcntl`、`posix`、`sysvmsg` 等扩展。`PHP` 只需安装最基本的扩展即可
diff --git "a/doc/1.9 - \345\206\205\346\240\270\345\217\202\346\225\260\350\260\203\346\225\264.md" "b/doc/1.10 - \345\206\205\346\240\270\345\217\202\346\225\260\350\260\203\346\225\264.md"
similarity index 100%
rename from "doc/1.9 - \345\206\205\346\240\270\345\217\202\346\225\260\350\260\203\346\225\264.md"
rename to "doc/1.10 - \345\206\205\346\240\270\345\217\202\346\225\260\350\260\203\346\225\264.md"
diff --git "a/doc/1.11 - \350\241\215\347\224\237\345\274\200\346\272\220\351\241\271\347\233\256.md" "b/doc/1.12 - \350\241\215\347\224\237\345\274\200\346\272\220\351\241\271\347\233\256.md"
similarity index 86%
rename from "doc/1.11 - \350\241\215\347\224\237\345\274\200\346\272\220\351\241\271\347\233\256.md"
rename to "doc/1.12 - \350\241\215\347\224\237\345\274\200\346\272\220\351\241\271\347\233\256.md"
index ed067e7..50d591c 100644
--- "a/doc/1.11 - \350\241\215\347\224\237\345\274\200\346\272\220\351\241\271\347\233\256.md"
+++ "b/doc/1.12 - \350\241\215\347\224\237\345\274\200\346\272\220\351\241\271\347\233\256.md"
@@ -4,14 +4,14 @@
----
* [Swoft](https://www.swoft.org) 首个基于 Swoole 原生协程的新时代 PHP 高性能协程全栈框架,内置协程网络服务器及常用的协程客户端,常驻内存,不依赖传统的 PHP-FPM,全异步非阻塞 IO 实现,以类似于同步客户端的写法实现异步客户端的使用,没有复杂的异步回调,没有繁琐的 yield, 有类似 Go 语言的协程、灵活的注解、强大的全局依赖注入容器、完善的服务治理、灵活强大的 AOP、标准的 PSR 规范实现等等,可以用于构建高性能的Web系统、API、中间件、基础服务等等。
* [EasySwoole](http://www.easyswoole.com/) EasySwoole 是一款基于Swoole Server 开发的常驻内存型PHP框架,专为API而生,摆脱传统PHP运行模式在进程唤起和文件加载上带来的性能损失。EasySwoole 高度封装了Swoole Server 而依旧维持Swoole Server 原有特性,支持同时混合监听HTTP、自定义TCP、UDP协议,让开发者以最低的学习成本和精力编写出多进程,可异步,高可用的应用服务。
+* [MixPHP](http://www.mixphp.cn/) 是一款基于 Swoole 的FPM、常驻内存、协程三模 PHP 高性能框架,MixPHP 秉承 "普及 PHP 常驻内存型解决方案,促进 PHP 往更后端发展" 的理念而创造,采用 Swoole 扩展作为底层引擎,围绕常驻内存的方式而设计,提供了 HTTP / WebSocket / Console 开发所需的众多开箱即用的组件,在其他 Swoole 框架都定位于大中型团队、庞大的 PHP 应用集群的时候,MixPHP 决定推动这项技术的普及,我们定位于众多的中小型企业、创业型公司,我们将 Swoole 的复杂度封装起来,用简单的编码方式呈现给用户,让更多的中级程序员也可打造高并发系统,努力让 Swoole 不再只是高级程序员的专利。
* [SwooleDistributed](http://sd.youwoxing.net) SwooleDistributed 老牌Swoole框架拥有最完善的开发工具以及最强大的功能,首创SDHelper开发者工具包和开发者调试命令集,可以进行单元测试,捕获客户端流量分析,可视化的进行远程断点联调,还具备代码覆盖率检测的功能(swoole与xdebug扩展不兼容,SDHelper无需xdebug扩展),并且内置组件极其丰富(类MQTT强悍的订阅发布/Actor模型/内存高速缓存/事件派发/进程管理/定时任务/AMQP任务调度/后台监控/集群/微服务/RPC/异步连接池/自定义命令等等),开发者可以直接使用加快开发进度。几乎所有的功能都支持集群化,单机切换到集群无需对代码做任何的修改。如果业务开发比较复杂比如(游戏开发)那么SD框架将是你的不二之选。
![](https://wiki.swoole.com/static/uploads/wiki/201807/04/759890562278.png)
![](https://wiki.swoole.com/static/uploads/wiki/201807/04/760320104883.png)
![](https://wiki.swoole.com/static/uploads/wiki/201807/04/760660259170.png)
-* [MixPHP](http://www.mixphp.cn/) 是一个基于 Swoole 的常驻内存型 PHP 高性能框架,围绕常驻内存的方式而设计,提供了 Web / Console 开发所需的众多开箱即用的组件,MixPHP 追求简单、实用主义,开发文档完善,试图让更多开发者以更低的学习成本享受到 Swoole 带来的高性能与全新的编程体验。
* [Swoolefy](https://github.com/bingcool/swoolefy) 基于swoole扩展实现的轻量级高性能的API和Web应用服务框架,高度封装了http,websocket,udp服务器,以及基于tcp实现可扩展,自定义协议的rpc服务器,同时支持composer包方式快速部署项目。基于易用,swoolefy抽象Event事件处理类,实现与底层的回调的解耦,专注逻辑业务,支持同步|异步调用,内置view、Log、session、mysql、redis、memcached、mongodb,mailer等常用组件。
* [Lawoole](https://github.com/lawoole/lawoole) 基于 Laravel 和 Swoole 的高性能 PHP 框架。借助 Swoole 的高性能特点,弥补了 Laravel 的性能缺陷。在大幅提升程序运行速度的情况下,能够使用到绝大部分 Laravel 中优秀的特性。在 Lawoole 中,你可以拥有与 Laravel 一致的开发体验,编写那些富有创造力的代码。
-* [CabalPHP](https://www.cabalphp.com/) 基于Swoole的**轻量、高效、全异步**开源框架,**自动生成API接口文档**,IDE下有完整的代码提示,相较于其他框架我们有完善的协程数据库和缓存引擎哦!
+* [CabalPHP](https://www.cabalphp.com/) 基于Swoole的轻量、高效、全异步开源框架,自动生成API接口文档,IDE下有完整的代码提示,相较于其他框架我们有完善的协程数据库和缓存引擎哦!
服务器
@@ -46,7 +46,7 @@ HTTP 应用框架
* [LaravelS](https://github.com/hhxsv5/laravel-s) 基于Swoole加速Laravel/Lumen,常驻内存,内置HTTP/WebSocket Server,支持TCP/UDP Server、协程的查询构造器与ORM(MySQL)、自定义进程、异步的事件监听、异步任务队列、毫秒级定时任务、平滑Reload,与Nginx配合搭建高可用分布式服务器群,开箱即用。
-* [Yii2-Swoole](https://github.com/tsingsun/yii2-swoole) 支持基于Yii2框架运行于Swoole中,同时可以很简单的支持Swool 1.0与2.0协程,自带mysql,redis连接池,可以使用Yii2的全栈框架来开发HTTP,WebSocket等网络服务。
+* [Yii2-Swoole](https://github.com/tsingsun/yii2-swoole) 支持基于Yii2框架运行于Swoole中,同时可以很简单的支持Swool 4.0协程与非协程,自带mysql,redis连接池,可以使用Yii2的全栈框架来开发HTTP,WebSocket等网络服务。
```
如果您有基于swoole开发新的开源项目,可以联系我们。将你的开源项目加入swoole官方推荐列表中。
```
\ No newline at end of file
diff --git "a/doc/1.11.1 - \346\241\206\346\236\266.md" "b/doc/1.12.1 - \346\241\206\346\236\266.md"
similarity index 91%
rename from "doc/1.11.1 - \346\241\206\346\236\266.md"
rename to "doc/1.12.1 - \346\241\206\346\236\266.md"
index 09941b9..1641410 100644
--- "a/doc/1.11.1 - \346\241\206\346\236\266.md"
+++ "b/doc/1.12.1 - \346\241\206\346\236\266.md"
@@ -1,32 +1,6 @@
# 框架
-* [Tencent-TSF](https://github.com/tencent-php/tsf) 腾讯公司推出的PHP协程框架,基于Swoole+PHP Generator实现Coroutine,可以像Golang一样用协程实现高并发服务器。
-* [swoole_framework](https://github.com/matyhtf/swoole_framework)基于swoole扩展开发的通用后端服务框架,包含了内置PHP应用服务器、FastCGI、WebSocket、Web框架等丰富的功能特性
-* [MixPHP](http://www.mixphp.cn/) 是一个基于 Swoole 的常驻内存型 PHP 高性能框架,围绕常驻内存的方式而设计,提供了 Web / Console 开发所需的众多开箱即用的组件,MixPHP 追求简单、实用主义,开发文档完善,试图让更多开发者以更低的学习成本享受到 Swoole 带来的高性能与全新的编程体验。
-* [LaravelS](https://github.com/hhxsv5/laravel-s) 基于Swoole加速Laravel/Lumen,常驻内存,内置HTTP/WebSocket Server,支持TCP/UDP Server、协程的查询构造器与ORM(MySQL)、自定义进程、异步的事件监听、异步任务队列、毫秒级定时任务、平滑Reload,与Nginx配合搭建高可用分布式服务器群,开箱即用。
-* [zphp](https://github.com/shenzhe/zphp)一个极轻的的,专用于游戏(社交,网页,移动)的服务器端开发框架.提供高性能实时通信方案。zphp使用swoole作为底层网络通信的框架。
-* [zapi](https://github.com/keaixiaou/zapi) 基于swoole+generator的http api异步非阻塞轻量级框架,内置mysql、redis、memcached、mongodb全套异步客户端的连接池,内置http异步客户端,近乎同步的写法,却是异步的调用,性能强悍
-* [zhttp](https://github.com/keaixiaou/zhttp) 基于swoole+generator的异步非阻塞轻量级web框架,内置mysql、redis、memcached、mongodb全套异步客户端的连接池,内置http异步客户端,近乎同步的写法,却是异步的调用,性能强悍
-* [swoole-yaf](https://github.com/LinkedDestiny/swoole-yaf) 结合PHP的Yaf框架和Swoole扩展的高性能PHP Web框架
-* [Swoole-Yaf](https://github.com/wenjun1055/swoole-yaf) 将Yaf框架和Swoole扩展提供的HttpServer结合在一起,server和框架高度结合形成超高性能的组合
-* [ciswoole](https://github.com/smalleyes/ciswoole) CodeIgniter 2.2 with Swoole_Http_Server
-* [owl-mvc](https://github.com/yeaha/owl-mvc) 基于 swoole_http_server 的一套PHP MVC框架
-* [hprose/hprose-php](https://github.com/hprose/hprose-php) 高性能远程对象调用服务,PHP 版本底层使用 swoole 实现了 http,https,tcp,tcp6,websocket, unix socket 服务器和 tcp,tcp6,unix socket 客户端。
-* [yiiSwoole](https://github.com/kcloze/yiiSwoole) Yii 1.1.16 with Swoole Http_Server,In high-concurrency situations,will be better than php-fpm
-* [Dora-RPC](https://github.com/xcl3721/Dora-RPC) 是基础swoole实现的轻量级高性能RPC框架,支持同步/异步调用,拥有有多任务并发及长链接维持特性
-* [Blink](https://github.com/bixuehujin/blink) 是一个为构建 “long running” 服务而生的 Web 微型高性能框架,它为构建 Web 应用程序提供简洁优雅的API,尽量的减轻我们的常规开发工作
-* [swPromise](https://github.com/coooold/swPromise) 基于swoole的PHP promise框架
-* [Aurora](https://github.com/zxz054321/aurora) 是一个建立在 Lightning 之上的高性能高并发框架,为追求极限性能而打造,底层由Phalcon + Swoole组合驱动,适用于需要支持高并发的场景,如API 接口、微服务等。
-* [Group](https://github.com/fucongcong/Group) 轻量级框架。基于swoole实现了定时任务,分布式任务队列,异步多进程服务(模拟map-reduce),结合hprose的rpc服务。
-* [Group-co](https://github.com/fucongcong/Group-Co) 优雅的异步协程框架,支持服务化搭建高并发httpserver,支持分布式使用,详情请戳链接。
-* [FastD](https://github.com/JanHuang/fastD) FastD 是一个支持 Swoole 的轻量级 Web 开发框架,可适用于对性能有要求的 API 场景,并且灵活的扩展性可以让开发者们更容易地建造自己的服务 (基于Swoole)
-* [Yii2-Swoole](https://github.com/tsingsun/yii2-swoole) 支持基于Yii2框架运行于Swoole中,同时可以很简单的支持Swool 1.0与2.0协程,自带mysql,redis连接池,可以使用Yii2的全栈框架来开发HTTP,WebSocket等网络服务。
-* [ultraman](https://github.com/zoooozz/ultraman) 结合PHP的Yaf框架和Swoole扩展的高性能PHP 封装成composer 及其容易上手
-* [Lawoole](https://github.com/lawoole/lawoole) 基于 Laravel 和 Swoole 的高性能 PHP 框架。借助 Swoole 的高性能特点,弥补了 Laravel 的性能缺陷。在大幅提升程序运行速度的情况下,能够使用到绝大部分 Laravel 中优秀的特性。在 Lawoole 中,你可以拥有与 Laravel 一致的开发体验,编写那些富有创造力的代码。
-* [CabalPHP](https://www.cabalphp.com/) 基于Swoole的**轻量、高效、全异步**开源框架,**自动生成API接口文档**,IDE下有完整的代码提示,相较于其他框架我们有完善的协程数据库和缓存引擎哦!
-
-
-Swoft:基于2.0原生协程的高性能PHP微服务框架
+Swoft:基于 Swoole 原生协程的新时代 PHP 全栈式协程框架
----
[https://github.com/swoft-cloud/swoft](https://github.com/swoft-cloud/swoft)
@@ -57,6 +31,41 @@ Swoft:基于2.0原生协程的高性能PHP微服务框架
- 强大的日志系统
- 跨平台热更新自动 Reload
+easySwoole 高性能HTTP框架
+-----
+easySwoole 专为API而生,是一款常驻内存化的PHP开发框架,摆脱传统PHP运行模式在进程唤起和文件加载上带来的性能损失,自带服务器功能,无需依赖Apache或Nginx运行。在web服务器模式下,支持多层级(组模式)控制器访问与多种事件回调,高度封装了Swoole Server 而依旧维持Swoole Server原有特性,支持在 Server 中监听自定义的TCP、UDP协议,让开发者可以最低的学习成本和精力,编写出多进程,可定时,可异步,高可用的应用服务。
+项目地址 : [https://www.easyswoole.com/](https://www.easyswoole.com/)
+
+MixPHP
+---
+[MixPHP](http://www.mixphp.cn/) 是一款基于 Swoole 的FPM、常驻内存、协程三模 PHP 高性能框架,MixPHP 秉承 "普及 PHP 常驻内存型解决方案,促进 PHP 往更后端发展" 的理念而创造,采用 Swoole 扩展作为底层引擎,围绕常驻内存的方式而设计,提供了 HTTP / WebSocket / Console 开发所需的众多开箱即用的组件,在其他 Swoole 框架都定位于大中型团队、庞大的 PHP 应用集群的时候,MixPHP 决定推动这项技术的普及,我们定位于众多的中小型企业、创业型公司,我们将 Swoole 的复杂度封装起来,用简单的编码方式呈现给用户,让更多的中级程序员也可打造高并发系统,努力让 Swoole 不再只是高级程序员的专利。
+
+---
+
+* [Tencent-TSF](https://github.com/tencent-php/tsf) 腾讯公司推出的PHP协程框架,基于Swoole+PHP Generator实现Coroutine,可以像Golang一样用协程实现高并发服务器。
+* [swoole_framework](https://github.com/matyhtf/swoole_framework)基于swoole扩展开发的通用后端服务框架,包含了内置PHP应用服务器、FastCGI、WebSocket、Web框架等丰富的功能特性
+* [LaravelS](https://github.com/hhxsv5/laravel-s) 基于Swoole加速Laravel/Lumen,常驻内存,内置HTTP/WebSocket Server,支持TCP/UDP Server、协程的查询构造器与ORM(MySQL)、自定义进程、异步的事件监听、异步任务队列、毫秒级定时任务、平滑Reload,与Nginx配合搭建高可用分布式服务器群,开箱即用。
+* [zphp](https://github.com/shenzhe/zphp)一个极轻的的,专用于游戏(社交,网页,移动)的服务器端开发框架.提供高性能实时通信方案。zphp使用swoole作为底层网络通信的框架。
+* [zapi](https://github.com/keaixiaou/zapi) 基于swoole+generator的http api异步非阻塞轻量级框架,内置mysql、redis、memcached、mongodb全套异步客户端的连接池,内置http异步客户端,近乎同步的写法,却是异步的调用,性能强悍
+* [zhttp](https://github.com/keaixiaou/zhttp) 基于swoole+generator的异步非阻塞轻量级web框架,内置mysql、redis、memcached、mongodb全套异步客户端的连接池,内置http异步客户端,近乎同步的写法,却是异步的调用,性能强悍
+* [swoole-yaf](https://github.com/LinkedDestiny/swoole-yaf) 结合PHP的Yaf框架和Swoole扩展的高性能PHP Web框架
+* [Swoole-Yaf](https://github.com/wenjun1055/swoole-yaf) 将Yaf框架和Swoole扩展提供的HttpServer结合在一起,server和框架高度结合形成超高性能的组合
+* [ciswoole](https://github.com/smalleyes/ciswoole) CodeIgniter 2.2 with Swoole_Http_Server
+* [owl-mvc](https://github.com/yeaha/owl-mvc) 基于 swoole_http_server 的一套PHP MVC框架
+* [hprose/hprose-php](https://github.com/hprose/hprose-php) 高性能远程对象调用服务,PHP 版本底层使用 swoole 实现了 http,https,tcp,tcp6,websocket, unix socket 服务器和 tcp,tcp6,unix socket 客户端。
+* [yiiSwoole](https://github.com/kcloze/yiiSwoole) Yii 1.1.16 with Swoole Http_Server,In high-concurrency situations,will be better than php-fpm
+* [Dora-RPC](https://github.com/xcl3721/Dora-RPC) 是基础swoole实现的轻量级高性能RPC框架,支持同步/异步调用,拥有有多任务并发及长链接维持特性
+* [Blink](https://github.com/bixuehujin/blink) 是一个为构建 “long running” 服务而生的 Web 微型高性能框架,它为构建 Web 应用程序提供简洁优雅的API,尽量的减轻我们的常规开发工作
+* [swPromise](https://github.com/coooold/swPromise) 基于swoole的PHP promise框架
+* [Aurora](https://github.com/zxz054321/aurora) 是一个建立在 Lightning 之上的高性能高并发框架,为追求极限性能而打造,底层由Phalcon + Swoole组合驱动,适用于需要支持高并发的场景,如API 接口、微服务等。
+* [Group](https://github.com/fucongcong/Group) 轻量级框架。基于swoole实现了定时任务,分布式任务队列,异步多进程服务(模拟map-reduce),结合hprose的rpc服务。
+* [Group-co](https://github.com/fucongcong/Group-Co) 优雅的异步协程框架,支持服务化搭建高并发httpserver,支持分布式使用,详情请戳链接。
+* [FastD](https://github.com/JanHuang/fastD) FastD 是一个支持 Swoole 的轻量级 Web 开发框架,可适用于对性能有要求的 API 场景,并且灵活的扩展性可以让开发者们更容易地建造自己的服务 (基于Swoole)
+* [Yii2-Swoole](https://github.com/tsingsun/yii2-swoole) 支持基于Yii2框架运行于Swoole中,同时可以很简单的支持Swool 1.0与2.0协程,自带mysql,redis连接池,可以使用Yii2的全栈框架来开发HTTP,WebSocket等网络服务。
+* [ultraman](https://github.com/zoooozz/ultraman) 结合PHP的Yaf框架和Swoole扩展的高性能PHP 封装成composer 及其容易上手
+* [Lawoole](https://github.com/lawoole/lawoole) 基于 Laravel 和 Swoole 的高性能 PHP 框架。借助 Swoole 的高性能特点,弥补了 Laravel 的性能缺陷。在大幅提升程序运行速度的情况下,能够使用到绝大部分 Laravel 中优秀的特性。在 Lawoole 中,你可以拥有与 Laravel 一致的开发体验,编写那些富有创造力的代码。
+* [CabalPHP](https://www.cabalphp.com/) 基于Swoole的**轻量、高效、全异步**开源框架,**自动生成API接口文档**,IDE下有完整的代码提示,相较于其他框架我们有完善的协程数据库和缓存引擎哦!
+
MyQEE 服务器类库
-----
@@ -79,8 +88,6 @@ MyQEE服务器类库特性:
* 更多的周边功能特性;
-
-
zys高性能服务框架
-----
基于Yaf和Swoole的i高性能Service框架,核心特性:
@@ -107,8 +114,3 @@ WebWorker-swoole高性能http服务框架
5. 支持中间件
6. redis支持原生同步和协程版本,只需要一个配置参数即可
7. mysql支持原生同步和协程版本,只需要一个配置参数即可
-
-easySwoole 高性能HTTP框架
------
-easySwoole 专为API而生,是一款常驻内存化的PHP开发框架,摆脱传统PHP运行模式在进程唤起和文件加载上带来的性能损失,自带服务器功能,无需依赖Apache或Nginx运行。在web服务器模式下,支持多层级(组模式)控制器访问与多种事件回调,高度封装了Swoole Server 而依旧维持Swoole Server原有特性,支持在 Server 中监听自定义的TCP、UDP协议,让开发者可以最低的学习成本和精力,编写出多进程,可定时,可异步,高可用的应用服务。
-项目地址 : [https://www.easyswoole.com/](https://www.easyswoole.com/)
\ No newline at end of file
diff --git "a/doc/1.11.2 - \345\267\245\345\205\267.md" "b/doc/1.12.2 - \345\267\245\345\205\267.md"
similarity index 78%
rename from "doc/1.11.2 - \345\267\245\345\205\267.md"
rename to "doc/1.12.2 - \345\267\245\345\205\267.md"
index 42475ae..9f81ff8 100644
--- "a/doc/1.11.2 - \345\267\245\345\205\267.md"
+++ "b/doc/1.12.2 - \345\267\245\345\205\267.md"
@@ -1,8 +1,6 @@
# 工具
* [swoole-ide-helper](https://github.com/EagleWu/swoole-ide-helper) 在IDE下自动识别swoole 扩展的类、函数、宏,自动补全函数名
-* [redis-async](https://github.com/swoole/redis-async) 基于swoole开发的异步Redis+连接池,性能非常强劲。使用redis-async开发的Web应用,QPS可以高达3.5万QPS,超过php-fpm+php-redis扩展性能的10倍。
-* [mysql-async](https://github.com/swoole/mysql-async) 基于swoole扩展开发的异步MySQL类库,内置连接池和SQL任务排队机制
* [swoole-crontab](https://github.com/osgochina/swoole-crontab) 基于swoole的定时器程序,支持秒级处理.
异步多进程处理。完全兼容crontab语法,且支持秒的配置
* [swoole-vmstat](https://github.com/smalleyes/swoole-vmstat) 运用swoole在浏览器更友好的实现vmstat
diff --git "a/doc/1.11.3 - \345\210\206\345\270\203\345\274\217.md" "b/doc/1.12.3 - \345\210\206\345\270\203\345\274\217.md"
similarity index 99%
rename from "doc/1.11.3 - \345\210\206\345\270\203\345\274\217.md"
rename to "doc/1.12.3 - \345\210\206\345\270\203\345\274\217.md"
index 74f50fe..c26bc1e 100644
--- "a/doc/1.11.3 - \345\210\206\345\270\203\345\274\217.md"
+++ "b/doc/1.12.3 - \345\210\206\345\270\203\345\274\217.md"
@@ -1,6 +1,6 @@
# 分布式
-SwooleDistributed(推荐使用)
+SwooleDistributed
-------
[SwooleDistributed](http://sd.youwoxing.net) swoole 分布式全栈框架框架,它的特点:
diff --git "a/doc/1.11.4 - \351\200\232\344\277\241\345\215\217\350\256\256.md" "b/doc/1.12.4 - \351\200\232\344\277\241\345\215\217\350\256\256.md"
similarity index 100%
rename from "doc/1.11.4 - \351\200\232\344\277\241\345\215\217\350\256\256.md"
rename to "doc/1.12.4 - \351\200\232\344\277\241\345\215\217\350\256\256.md"
diff --git "a/doc/1.12 - \347\224\250\346\210\267\344\270\216\346\241\210\344\276\213.md" "b/doc/1.13 - \347\224\250\346\210\267\344\270\216\346\241\210\344\276\213.md"
similarity index 100%
rename from "doc/1.12 - \347\224\250\346\210\267\344\270\216\346\241\210\344\276\213.md"
rename to "doc/1.13 - \347\224\250\346\210\267\344\270\216\346\241\210\344\276\213.md"
diff --git "a/doc/1.12.1 - \347\211\251\350\201\224\347\275\221\351\241\271\347\233\256.md" "b/doc/1.13.1 - \347\211\251\350\201\224\347\275\221\351\241\271\347\233\256.md"
similarity index 100%
rename from "doc/1.12.1 - \347\211\251\350\201\224\347\275\221\351\241\271\347\233\256.md"
rename to "doc/1.13.1 - \347\211\251\350\201\224\347\275\221\351\241\271\347\233\256.md"
diff --git "a/doc/1.12.2 - \347\275\221\347\273\234\346\270\270\346\210\217.md" "b/doc/1.13.2 - \347\275\221\347\273\234\346\270\270\346\210\217.md"
similarity index 100%
rename from "doc/1.12.2 - \347\275\221\347\273\234\346\270\270\346\210\217.md"
rename to "doc/1.13.2 - \347\275\221\347\273\234\346\270\270\346\210\217.md"
diff --git "a/doc/1.12.3 - \350\205\276\350\256\257\357\274\210Tencent\357\274\211.md" "b/doc/1.13.3 - \350\205\276\350\256\257\357\274\210Tencent\357\274\211.md"
similarity index 100%
rename from "doc/1.12.3 - \350\205\276\350\256\257\357\274\210Tencent\357\274\211.md"
rename to "doc/1.13.3 - \350\205\276\350\256\257\357\274\210Tencent\357\274\211.md"
diff --git "a/doc/1.12.4 - \347\231\276\345\272\246\357\274\210Baidu.com\357\274\211.md" "b/doc/1.13.4 - \347\231\276\345\272\246\357\274\210Baidu.com\357\274\211.md"
similarity index 100%
rename from "doc/1.12.4 - \347\231\276\345\272\246\357\274\210Baidu.com\357\274\211.md"
rename to "doc/1.13.4 - \347\231\276\345\272\246\357\274\210Baidu.com\357\274\211.md"
diff --git "a/doc/1.12.5 - \351\230\205\346\226\207\351\233\206\345\233\242.md" "b/doc/1.13.5 - \351\230\205\346\226\207\351\233\206\345\233\242.md"
similarity index 100%
rename from "doc/1.12.5 - \351\230\205\346\226\207\351\233\206\345\233\242.md"
rename to "doc/1.13.5 - \351\230\205\346\226\207\351\233\206\345\233\242.md"
diff --git "a/doc/1.12.6 - BiliBili\357\274\210\345\223\224\345\223\251\345\223\224\345\223\251\357\274\211.md" "b/doc/1.13.6 - BiliBili\357\274\210\345\223\224\345\223\251\345\223\224\345\223\251\357\274\211.md"
similarity index 100%
rename from "doc/1.12.6 - BiliBili\357\274\210\345\223\224\345\223\251\345\223\224\345\223\251\357\274\211.md"
rename to "doc/1.13.6 - BiliBili\357\274\210\345\223\224\345\223\251\345\223\224\345\223\251\357\274\211.md"
diff --git "a/doc/1.12.7 - \350\275\246\350\275\256\344\272\222\350\201\224\357\274\210chelun.com\357\274\211.md" "b/doc/1.13.7 - \350\275\246\350\275\256\344\272\222\350\201\224\357\274\210chelun.com\357\274\211.md"
similarity index 100%
rename from "doc/1.12.7 - \350\275\246\350\275\256\344\272\222\350\201\224\357\274\210chelun.com\357\274\211.md"
rename to "doc/1.13.7 - \350\275\246\350\275\256\344\272\222\350\201\224\357\274\210chelun.com\357\274\211.md"
diff --git "a/doc/1.12.8 - (\346\215\236\346\234\210\347\213\227) \346\270\270\346\210\217\347\244\276\345\214\272.md" "b/doc/1.13.8 - (\346\215\236\346\234\210\347\213\227) \346\270\270\346\210\217\347\244\276\345\214\272.md"
similarity index 100%
rename from "doc/1.12.8 - (\346\215\236\346\234\210\347\213\227) \346\270\270\346\210\217\347\244\276\345\214\272.md"
rename to "doc/1.13.8 - (\346\215\236\346\234\210\347\213\227) \346\270\270\346\210\217\347\244\276\345\214\272.md"
diff --git "a/doc/1.13 - \346\217\220\344\272\244\351\224\231\350\257\257\346\212\245\345\221\212.md" "b/doc/1.14 - \346\217\220\344\272\244\351\224\231\350\257\257\346\212\245\345\221\212.md"
similarity index 99%
rename from "doc/1.13 - \346\217\220\344\272\244\351\224\231\350\257\257\346\212\245\345\221\212.md"
rename to "doc/1.14 - \346\217\220\344\272\244\351\224\231\350\257\257\346\212\245\345\221\212.md"
index 38add13..8029743 100644
--- "a/doc/1.13 - \346\217\220\344\272\244\351\224\231\350\257\257\346\212\245\345\221\212.md"
+++ "b/doc/1.14 - \346\217\220\344\272\244\351\224\231\350\257\257\346\212\245\345\221\212.md"
@@ -86,7 +86,7 @@ uname -a
#### gcc
```shell
-cc -v
+gcc -v
```
#### openssl
diff --git "a/doc/1.14.3 - \345\234\250phpinfo\344\270\255\346\234\211\345\234\250php-m\344\270\255\346\262\241\346\234\211.md" "b/doc/1.14.3 - \345\234\250phpinfo\344\270\255\346\234\211\345\234\250php-m\344\270\255\346\262\241\346\234\211.md"
deleted file mode 100644
index 25a56bb..0000000
--- "a/doc/1.14.3 - \345\234\250phpinfo\344\270\255\346\234\211\345\234\250php-m\344\270\255\346\262\241\346\234\211.md"
+++ /dev/null
@@ -1,24 +0,0 @@
-# 在phpinfo中有在php-m中没有
-
-编译安装完swoole后,在php-fpm/apache的phpinfo页面中有,在命令行的php -m中没有。原因可能是cli/php-fpm/apache使用不同的php.ini配置
-
-一、确认php.ini的位置
-------
-cli命令行下
-```shell
-php -i|grep php.ini
-```
-
-php-fpm/apache,查看`phpinfo页面`找到php.ini的绝对路径。
-
-二、查看对应php.ini是否有extension=swoole.so
-------
-```shell
-cat /usr/local/lib/php.ini | grep swoole.so
-```
-
----
-
-# 为什么命令行能看到网页上看不到
-
-仔细看上面的, 说明cli和apache/fpm模式下的ini配置文件是在不同位置的, 需要找到正确的ini文件.
\ No newline at end of file
diff --git "a/doc/1.14 - \345\270\270\350\247\201\351\227\256\351\242\230.md" "b/doc/1.15 - \345\270\270\350\247\201\351\227\256\351\242\230.md"
similarity index 100%
rename from "doc/1.14 - \345\270\270\350\247\201\351\227\256\351\242\230.md"
rename to "doc/1.15 - \345\270\270\350\247\201\351\227\256\351\242\230.md"
diff --git "a/doc/1.14.1 - \345\215\207\347\272\247swoole\347\211\210\346\234\254\347\232\204\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/doc/1.15.1 - \345\215\207\347\272\247swoole\347\211\210\346\234\254\347\232\204\345\270\270\350\247\201\351\227\256\351\242\230.md"
similarity index 100%
rename from "doc/1.14.1 - \345\215\207\347\272\247swoole\347\211\210\346\234\254\347\232\204\345\270\270\350\247\201\351\227\256\351\242\230.md"
rename to "doc/1.15.1 - \345\215\207\347\272\247swoole\347\211\210\346\234\254\347\232\204\345\270\270\350\247\201\351\227\256\351\242\230.md"
diff --git a/doc/1.14.10 - my_global.h: No such file or directory.md b/doc/1.15.10 - my_global.h: No such file or directory.md
similarity index 100%
rename from doc/1.14.10 - my_global.h: No such file or directory.md
rename to doc/1.15.10 - my_global.h: No such file or directory.md
diff --git a/doc/1.14.11 - undefined symbol: __sync_bool_compare_and_swap_4.md b/doc/1.15.11 - undefined symbol: __sync_bool_compare_and_swap_4.md
similarity index 100%
rename from doc/1.14.11 - undefined symbol: __sync_bool_compare_and_swap_4.md
rename to doc/1.15.11 - undefined symbol: __sync_bool_compare_and_swap_4.md
diff --git "a/doc/1.14.12 - \345\255\246\344\271\240Swoole\351\234\200\350\246\201\346\216\214\346\217\241\345\223\252\344\272\233\345\237\272\347\241\200\347\237\245\350\257\206.md" "b/doc/1.15.12 - \345\255\246\344\271\240Swoole\351\234\200\350\246\201\346\216\214\346\217\241\345\223\252\344\272\233\345\237\272\347\241\200\347\237\245\350\257\206.md"
similarity index 100%
rename from "doc/1.14.12 - \345\255\246\344\271\240Swoole\351\234\200\350\246\201\346\216\214\346\217\241\345\223\252\344\272\233\345\237\272\347\241\200\347\237\245\350\257\206.md"
rename to "doc/1.15.12 - \345\255\246\344\271\240Swoole\351\234\200\350\246\201\346\216\214\346\217\241\345\223\252\344\272\233\345\237\272\347\241\200\347\237\245\350\257\206.md"
diff --git "a/doc/1.14.13 - \345\220\214\346\255\245\351\230\273\345\241\236\344\270\216\345\274\202\346\255\245\351\235\236\351\230\273\345\241\236\351\200\202\347\224\250\345\234\272\346\231\257.md" "b/doc/1.15.13 - \345\220\214\346\255\245\351\230\273\345\241\236\344\270\216\345\274\202\346\255\245\351\235\236\351\230\273\345\241\236\351\200\202\347\224\250\345\234\272\346\231\257.md"
similarity index 100%
rename from "doc/1.14.13 - \345\220\214\346\255\245\351\230\273\345\241\236\344\270\216\345\274\202\346\255\245\351\235\236\351\230\273\345\241\236\351\200\202\347\224\250\345\234\272\346\231\257.md"
rename to "doc/1.15.13 - \345\220\214\346\255\245\351\230\273\345\241\236\344\270\216\345\274\202\346\255\245\351\235\236\351\230\273\345\241\236\351\200\202\347\224\250\345\234\272\346\231\257.md"
diff --git "a/doc/1.14.14 - PHP7\347\216\257\345\242\203\344\270\213\345\207\272\347\216\260zend_mm_heap corrupted.md" "b/doc/1.15.14 - PHP7\347\216\257\345\242\203\344\270\213\345\207\272\347\216\260zend_mm_heap corrupted.md"
similarity index 100%
rename from "doc/1.14.14 - PHP7\347\216\257\345\242\203\344\270\213\345\207\272\347\216\260zend_mm_heap corrupted.md"
rename to "doc/1.15.14 - PHP7\347\216\257\345\242\203\344\270\213\345\207\272\347\216\260zend_mm_heap corrupted.md"
diff --git "a/doc/1.14.15 - swoole\351\241\271\347\233\256\350\265\267\346\272\220\345\222\214\345\220\215\345\255\227\347\224\261\346\235\245.md" "b/doc/1.15.15 - swoole\351\241\271\347\233\256\350\265\267\346\272\220\345\222\214\345\220\215\345\255\227\347\224\261\346\235\245.md"
similarity index 100%
rename from "doc/1.14.15 - swoole\351\241\271\347\233\256\350\265\267\346\272\220\345\222\214\345\220\215\345\255\227\347\224\261\346\235\245.md"
rename to "doc/1.15.15 - swoole\351\241\271\347\233\256\350\265\267\346\272\220\345\222\214\345\220\215\345\255\227\347\224\261\346\235\245.md"
diff --git "a/doc/1.15.16 - swFactoryProcess_finish (ERROR 1004): send %d byte failed, because session#%d is closed \357\274\217 swFactoryProcess_finish (ERROR 1005): connection[fd=%d] does not exists.md" "b/doc/1.15.16 - swFactoryProcess_finish (ERROR 1004): send %d byte failed, because session#%d is closed \357\274\217 swFactoryProcess_finish (ERROR 1005): connection[fd=%d] does not exists.md"
new file mode 100644
index 0000000..ca69238
--- /dev/null
+++ "b/doc/1.15.16 - swFactoryProcess_finish (ERROR 1004): send %d byte failed, because session#%d is closed \357\274\217 swFactoryProcess_finish (ERROR 1005): connection[fd=%d] does not exists.md"
@@ -0,0 +1,16 @@
+# swFactoryProcess_finish (ERROR 1004): send %d byte failed, because session#%d is closed / swFactoryProcess_finish (ERROR 1005): connection[fd=%d] does not exists
+
+---
+
+```
+NOTICE swFactoryProcess_finish (ERROR 1004): send %d byte failed, because session#%d is closed.
+NOTICE swFactoryProcess_finish (ERROR 1005): connection[fd=%d] does not exists.
+```
+
+此警告已降级为NOTICE级别
+该提示着对端(客户端)切断了连接, 并不代表这是一个错误.
+
+一般出现在:
+
+1. 频繁刷新页面, 页面未加载完就关闭
+2. ab/wrk压力测试指定了测试时间, 时间到时未结束的请求会被强行切断
\ No newline at end of file
diff --git "a/doc/1.14.2 - \347\224\237\346\210\220\345\217\257\345\210\206\345\217\221\347\232\204\344\272\214\350\277\233\345\210\266swoole\347\211\210\346\234\254.md" "b/doc/1.15.2 - \347\224\237\346\210\220\345\217\257\345\210\206\345\217\221\347\232\204\344\272\214\350\277\233\345\210\266swoole\347\211\210\346\234\254.md"
similarity index 100%
rename from "doc/1.14.2 - \347\224\237\346\210\220\345\217\257\345\210\206\345\217\221\347\232\204\344\272\214\350\277\233\345\210\266swoole\347\211\210\346\234\254.md"
rename to "doc/1.15.2 - \347\224\237\346\210\220\345\217\257\345\210\206\345\217\221\347\232\204\344\272\214\350\277\233\345\210\266swoole\347\211\210\346\234\254.md"
diff --git "a/doc/1.15.3 - \345\234\250phpinfo\344\270\255\346\234\211\345\234\250php -m\344\270\255\346\262\241\346\234\211.md" "b/doc/1.15.3 - \345\234\250phpinfo\344\270\255\346\234\211\345\234\250php -m\344\270\255\346\262\241\346\234\211.md"
new file mode 100644
index 0000000..27dde81
--- /dev/null
+++ "b/doc/1.15.3 - \345\234\250phpinfo\344\270\255\346\234\211\345\234\250php -m\344\270\255\346\262\241\346\234\211.md"
@@ -0,0 +1,43 @@
+# 在phpinfo中有在php -m中没有
+
+# 先确认CLI模式下是否有
+命令行输入`php --ri swoole`
+
+如果输出了swoole的扩展信息就说明你安装成功了!
+
+**99.999%的人在此步成功就可以直接使用swoole了**
+
+不需要管`php -m`或者`phpinfo`网页打印出来是否有swoole
+
+因为swoole是运行在cli模式下的, 在传统的fpm模式下功能十分有限
+
+fpm模式下任何异步/协程等主要功能都**不可以使用**, 99.999%的人都不能在fpm模式下得到想要的东西, 却纠结为什么fpm模式下没有扩展信息
+
+**先确定你是否真正理解了swoole的运行模式, 再继续追究安装信息问题!**
+
+
+# 原因
+编译安装完swoole后,在php-fpm/apache的phpinfo页面中有,在命令行的php -m中没有。原因可能是cli/php-fpm/apache使用不同的php.ini配置
+
+# 解决办法
+
+一、确认php.ini的位置
+------
+cli命令行下
+```shell
+php -i|grep php.ini
+```
+
+php-fpm/apache,查看`phpinfo页面`找到php.ini的绝对路径。
+
+二、查看对应php.ini是否有extension=swoole.so
+------
+```shell
+cat /usr/local/lib/php.ini | grep swoole.so
+```
+
+---
+
+# 为什么命令行能看到网页上看不到
+
+仔细看上面的, 说明cli和apache/fpm模式下的ini配置文件是在不同位置的, 需要找到正确的ini文件.
\ No newline at end of file
diff --git "a/doc/1.14.4 - Connection refused\346\230\257\346\200\216\344\271\210\345\233\236\344\272\213.md" "b/doc/1.15.4 - Connection refused\346\230\257\346\200\216\344\271\210\345\233\236\344\272\213.md"
similarity index 100%
rename from "doc/1.14.4 - Connection refused\346\230\257\346\200\216\344\271\210\345\233\236\344\272\213.md"
rename to "doc/1.15.4 - Connection refused\346\230\257\346\200\216\344\271\210\345\233\236\344\272\213.md"
diff --git a/doc/1.14.5 - Resource temporarily unavailable [11].md b/doc/1.15.5 - Resource temporarily unavailable [11].md
similarity index 100%
rename from doc/1.14.5 - Resource temporarily unavailable [11].md
rename to doc/1.15.5 - Resource temporarily unavailable [11].md
diff --git a/doc/1.14.6 - Cannot assign requested address [99].md b/doc/1.15.6 - Cannot assign requested address [99].md
similarity index 100%
rename from doc/1.14.6 - Cannot assign requested address [99].md
rename to doc/1.15.6 - Cannot assign requested address [99].md
diff --git "a/doc/1.14.7 - swoole\344\270\216node.js\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md" "b/doc/1.15.7 - swoole\344\270\216node.js\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md"
similarity index 100%
rename from "doc/1.14.7 - swoole\344\270\216node.js\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md"
rename to "doc/1.15.7 - swoole\344\270\216node.js\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md"
diff --git "a/doc/1.14.8 - swoole\344\270\216golang\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md" "b/doc/1.15.8 - swoole\344\270\216golang\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md"
similarity index 100%
rename from "doc/1.14.8 - swoole\344\270\216golang\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md"
rename to "doc/1.15.8 - swoole\344\270\216golang\347\233\270\346\257\224\346\234\211\345\223\252\344\272\233\344\274\230\345\212\277.md"
diff --git a/doc/1.14.9 - pcre.h: No such file or directory.md b/doc/1.15.9 - pcre.h: No such file or directory.md
similarity index 56%
rename from doc/1.14.9 - pcre.h: No such file or directory.md
rename to doc/1.15.9 - pcre.h: No such file or directory.md
index 0a6332c..8474004 100644
--- a/doc/1.14.9 - pcre.h: No such file or directory.md
+++ b/doc/1.15.9 - pcre.h: No such file or directory.md
@@ -10,14 +10,16 @@ fatal error: pcre.h: No such file or directory
ubuntu/debian:
-----
```shell
-apt-get install libpcre3 libpcre3-dev
+sudo apt-get install libpcre3 libpcre3-dev
```
centos/redhat:
----
```shell
-yum install pcre-devel
+sudo yum install pcre-devel
```
其他Linux:
----
-到[PCRE官方网站](http://www.pcre.org/)下载源码包,编译安装pcre库。
+到[PCRE官方网站](http://www.pcre.org/)下载源码包,编译安装`pcre`库。
+
+安装好`PCRE`库后需要重新编译安装`swoole`,然后使用`php --ri swoole`查看`swoole`扩展相关信息中是否有`pcre => enabled`
diff --git "a/doc/1.2 - \347\274\226\350\257\221\345\256\211\350\243\205.md" "b/doc/1.2 - \347\274\226\350\257\221\345\256\211\350\243\205.md"
index 638f7d5..f501984 100644
--- "a/doc/1.2 - \347\274\226\350\257\221\345\256\211\350\243\205.md"
+++ "b/doc/1.2 - \347\274\226\350\257\221\345\256\211\350\243\205.md"
@@ -2,7 +2,8 @@
`Swoole`扩展是按照`PHP`标准扩展构建的。使用`phpize`来生成编译检测脚本,`./configure`来做编译配置检测,`make`进行编译,`make install`进行安装。
-* 请下载`releases`版本的`swoole`,直接从`github`主干上拉取最新代码可能会编译不过
+* **请下载`releases`版本的`swoole`,直接从`github`主干上拉取最新代码可能会编译不过**
+* **如无特殊需求, 请务必编译安装`swoole`的最新版本**
* 如果当前用户不是`root`,可能没有`PHP`安装目录的写权限,安装时需要`sudo`或者`su`
* 如果是在`git`分支上直接`git pull`更新代码,重新编译前务必要执行`make clean`
@@ -25,17 +26,21 @@ pcre (centos系统可以执行命令:yum install pcre-devel)
下载源代码包后,在终端进入源码目录,执行下面的命令进行编译和安装
+新手编译示例
+---
```shell
cd swoole
-phpize
-./configure
-make
+sudo phpize (ubuntu 没有安装phpize可执行命令:sudo apt-get install php-dev来安装phpize)
+sudo ./configure
+sudo make
sudo make install
```
-完整编译示例
+进阶完整编译示例
---
-以下脚本会下载并编译master分支的swoole源码
+> 初次接触swoole的开发者请先尝试上方的简单编译
+
+以下脚本会下载并编译master分支的swoole源码, 需保证你已安装所有依赖, 否则会遇到各种依赖错误
```shell
mkdir -p ~/build && \
cd ~/build && \
diff --git "a/doc/1.2.1 - \347\274\226\350\257\221\345\217\202\346\225\260.md" "b/doc/1.2.1 - \347\274\226\350\257\221\345\217\202\346\225\260.md"
index 74bb74c..0695157 100644
--- "a/doc/1.2.1 - \347\274\226\350\257\221\345\217\202\346\225\260.md"
+++ "b/doc/1.2.1 - \347\274\226\350\257\221\345\217\202\346\225\260.md"
@@ -1,91 +1,109 @@
# 编译参数
-## 新手警告: 不在此列表中的编译参数, 任何情况都请不要使用
+## ⚠️新手警告: 不在此列表中的编译参数, 任何情况都请不要使用
这里是`./configure`编译配置的额外参数,用于开启某些特性
> `1.8.7`或更高版本不再需要设置`--enable-async-mysql`和`--enable-async-httpclient`,`async_mysql`和`async_httpclient`改为内置
> `4.0.1`或更高版本后不再需要设置`--enable-coroutine`
-
+------
-`--enable-sockets`
+## ☺ 通用参数
+
+--enable-sockets
----
增加对`sockets`资源的支持。开启此参数,`swoole_event_add`就可以添加`sockets`扩展创建的连接到`swoole`的事件循环中。另外`Server`和`Client`的`getSocket()`方法也需要依赖此编译参数。
>依赖`sockets`扩展
-`--enable-openssl`
+--enable-openssl
----
启用`SSL`支持
>使用操作系统提供的`libssl.so`动态连接库
-`--with-openssl-dir`
+--with-openssl-dir
----
-指定`openssl`库的路径。`--with-openssl-dir=/opt/openssl/`
+启用`SSL`支持 并 指定`openssl`库的路径, 需跟上路径参数: `--with-openssl-dir=/opt/openssl/`
-`--enable-http2`
+--enable-http2
----
增加对HTTP2的支持
>依赖`nghttp2`库
-`--enable-async-redis`
+--with-nghttp2-dir
+----
+增加对HTTP2的支持 并 指定`nghttp2`库的路径, 需跟上路径参数: `--with-nghttp2-dir=/opt/nghttp2/`
+> 需要 `4.2.0` 及以上版本
+
+--enable-async-redis
----
增加异步Redis客户端支持
>依赖`hiredis`库
-`--enable-mysqlnd`
-----
-启用`mysqlnd`支持,启用`swoole_mysql::escapse`方法。启用此参数后,`PHP`必须有`mysqlnd`模块,否则会导致`swoole`无法运行。
->依赖`mysqlnd`模块
+> 4.2.x版本可能会显示`redis-client`而没有`async`字样, 实际上是一样的
-`--enable-coroutine`
+--with-hiredis-dir
----
-> 4.0.1版本后移除了此编译选项, 强制打开, 可使用$server->set动态开关
+增加异步Redis客户端支持 并 指定`hiredis`库的路径, 需跟上路径参数: `--with-hiredis-dir=/opt/hiredis/`
+> 需要 `4.2.0` 及以上版本
-> enable_coroutine动态配置请见[文档](https://wiki.swoole.com/wiki/page/949.html)
-
-启用协程
+--enable-mysqlnd
+----
+启用`mysqlnd`支持,启用`swoole_mysql::escapse`方法。启用此参数后,`PHP`必须有`mysqlnd`模块,否则会导致`swoole`无法运行。
+>依赖`mysqlnd`模块
-`--enable-coroutine-postgresql `
+--enable-coroutine-postgresql
----
启用协程Postgresql客户端
>依赖libpq库
-`--with-libpq-dir`
+--with-libpq-dir
----
指定`libpq`库的路径. `--with-libpq-dir=/etc/postgresql`
-## Debug参数
+## ☻ 已废弃的编译参数
+
+--enable-coroutine
+----
+> 4.0.1版本后移除了此编译选项, 默认强制打开, 可使用$server->set动态开关
+
+> enable_coroutine动态配置请见[文档](https://wiki.swoole.com/wiki/page/949.html)
+
+启用协程
+
+
+
+## Debug参数
-`--enable-swoole-debug`
+--enable-swoole-debug | --enable-debug-log(>=4.2.0)
----
打开内核DEBUG日志。**生产环境不可以启用**
-`--enable-trace-log`
+--enable-trace-log
----
打开追踪日志,开启此选项后swoole将打印各类细节的调试日志, 仅内核开发时使用
-## 以下试验性质选项轻易绝不要开启
+## ☠️以下试验性质选项轻易绝不要开启
-`--enable-ringbuffer`
+--enable-ringbuffer
----
开启`RingBuffer`内存池
> 此设置为试验性质,主要用于提升性能,生产环境请不要开启
-`--enable-timewheel`
+--enable-timewheel
----
启用时间轮算法,优化心跳检测性能
> 此设置为试验性质
-## 以下选项需要在你知道它是如何工作的时候方可添加
+## ☠️以下选项需要在你知道它是如何工作的时候方可添加
-`--enable-asan`
+--enable-asan
---
详情: https://wiki.swoole.com/wiki/page/939.html
@@ -95,11 +113,11 @@
## 以下选项是编译PHP而不是Swoole时使用的
-`--enable-swoole`
+--enable-swoole
---
使用swoole扩展
-`--enable-swoole-static`
+--enable-swoole-static
---
将Swoole静态编译内嵌到PHP
diff --git "a/doc/1.2.2 - \345\270\270\350\247\201\351\224\231\350\257\257.md" "b/doc/1.2.2 - \345\270\270\350\247\201\351\224\231\350\257\257.md"
index a0cf7a2..18e6ade 100644
--- "a/doc/1.2.2 - \345\270\270\350\247\201\351\224\231\350\257\257.md"
+++ "b/doc/1.2.2 - \345\270\270\350\247\201\351\224\231\350\257\257.md"
@@ -42,16 +42,8 @@ make install需要root权限,如果不是以root用户登录的,请用sudo
修改了php.ini后,php -m或phpinfo中没有swoole
----
-```shell
-php -i|grep php.ini
-```
-查看加载的php.ini路径,确认加载了正确的php.ini。
+[请移步该文档](https://wiki.swoole.com/wiki/page/351.html)
-修改php.ini,打开错误显示,查看是否存在启动时错误。
-```
-display_errors => On
-display_startup_errors => On
-```
缺少hiredis.h
----
编译配置时启用`--enable-async-redis`,但没有安装`hiredis`库,编译时会报`fatal error: 'hiredis/hiredis.h' file not found`,请安装`hiredis`库或者去掉`--enable-async-redis`选项。
diff --git "a/doc/1.3.10 - \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md" "b/doc/1.3.10 - \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md"
index 2ba7d24..6b06300 100644
--- "a/doc/1.3.10 - \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md"
+++ "b/doc/1.3.10 - \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md"
@@ -37,6 +37,7 @@ $redis->connect('127.0.0.1', 6379, function ($redis, $result) {
});
});
```
+`Swoole\Redis`需要`Swoole`编译安装`hiredis`,详细文档参见[异步Redis客户端](https://wiki.swoole.com/wiki/page/p-redis.html "异步Redis客户端")
Http
---
diff --git "a/doc/1.5 - \347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225.md" "b/doc/1.5 - \347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225.md"
index 831827f..109f9e5 100644
--- "a/doc/1.5 - \347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225.md"
+++ "b/doc/1.5 - \347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225.md"
@@ -8,12 +8,11 @@
----
```
-稳定版:v1.10.5
-预览版:v4.0.0
+4.0.x 最新版
```
> `1.x`/`2.x`分支已进入特性锁定期,不再开发新功能,仅修复`BUG`
-> `2.x`/`4.x`版本可通过增加`--disable-coroutine`关闭协程特性,使其变为非协程版本
+> `4.x`版本可通过[设置`enable-coroutine`关闭协程特性](https://wiki.swoole.com/wiki/page/949.html),使其变为非协程版本
版本类型
-----
diff --git a/doc/1.5.1 - 4.0.4.md b/doc/1.5.1 - 4.0.4.md
deleted file mode 100644
index 79448a5..0000000
--- a/doc/1.5.1 - 4.0.4.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# 4.0.4
-
-* 修复`WebSocket`协程客户端接收超时关闭连接的问题
-* 修复`PHP`类继承扩展内置类未调用`parent::__construct`导致出现`crash`的问题
-
diff --git a/doc/1.5.1 - 4.2.2.md b/doc/1.5.1 - 4.2.2.md
new file mode 100644
index 0000000..cdd9e18
--- /dev/null
+++ b/doc/1.5.1 - 4.2.2.md
@@ -0,0 +1,16 @@
+# 4.2.2
+
++ 重构`addListener`, 现在可以以任意顺序添加新的服务监听
++ 支持同时混合启用`http`, `http2`, `websocket`, `tcp`服务
++ 补全协程redis客户端方法参数定义
+* 兼容PHP70中event_wait结束后EG(scope)未还原导致无法访问私有属性
+* 修复MacOS下sendfile数据错乱
+* HTTP协议实现上的优化
+* 修复尝试连接已连接的异步redis发生coredump的bug
+* 修复socket hook中socket构造失败产生coredump的bug
+* 修复MySQL客户端协议处理参数绑定NULL的bug
+* alpine依赖兼容性优化
+* cygwin兼容性优化
+* 底层代码大清理, 删除所有TSRM宏, PHP5兼容宏与函数, 减少无用的栈分配和多重指针, 重新开启FASTZPP提高参数解析性能
+* 错误优化, swoole底层出现问题时将会产生一个包含版本号的错误反馈提示
+* 修复读取被unset的对象属性时返回非法指针的bug
\ No newline at end of file
diff --git a/doc/1.5.4 - 4.0.1.md b/doc/1.5.10 - 4.0.1.md
similarity index 100%
rename from doc/1.5.4 - 4.0.1.md
rename to doc/1.5.10 - 4.0.1.md
diff --git a/doc/1.5.5 - 4.0.0.md b/doc/1.5.11 - 4.0.0.md
similarity index 100%
rename from doc/1.5.5 - 4.0.0.md
rename to doc/1.5.11 - 4.0.0.md
diff --git a/doc/1.5.2 - 4.2.1.md b/doc/1.5.2 - 4.2.1.md
new file mode 100644
index 0000000..32fbba9
--- /dev/null
+++ b/doc/1.5.2 - 4.2.1.md
@@ -0,0 +1,8 @@
+# 4.2.1
+
++ 此版本是基于上个版本做出了一些错误修复
+* 修复某些环境下没有time_nanosleep导致的编译失败
+* 修复PHP-ZTS下的载入错误
+* 修复dispatch模式为7时使用协程出现Bad file descriptor的错误
+* 修复协程exit拦截器不生效
+* 修复过长域名解析缓冲区不足导致coredump
diff --git a/doc/1.5.3 - 4.2.0.md b/doc/1.5.3 - 4.2.0.md
new file mode 100644
index 0000000..c29c008
--- /dev/null
+++ b/doc/1.5.3 - 4.2.0.md
@@ -0,0 +1,22 @@
+# 4.2.0
+
++ 增加新的协程hook, `tcp`、`udp`、`ssl`, `tls`, `sleep`, `usleep`, 以及文件读写,`mkdir`等, 自动协程化
++ 增加 服务端/客户端 直接发送 `swoole_websocket_frame` 对象的能力, 支持任意类型的`frame`构造和收发, 支持`frame`的字符串化
++ 重构`AIO`
++ 增加`Process\Pool::getProcess`方法
++ 增加编译参数 `--with-hiredis-dir`, `--with-nghttp2-dir`的支持
+* 修复协程MySQL客户端execute不支持null参数
+* 强化`send_yield`, timeout内支持自动重试
+* 强化定时器轮数检测, 修复毫秒级超短定时器执行错误
+* 默认启用`TCP_NODELAY`, 关闭`Nagle算法`, 降低延迟
+* 提升PECL打包的规范性
+* 重新支持发送自定义`content-length`为0的HTTP-header
+* 修复在PHP7.0中协程yield时`EG(scope)`未切换导致的类中Private/Protect属性不可访问的问题
+* 修复`websocket_server` opcode和finish参数解析错误的bug
+* 修复`async_dns_lookup`的bug
+* 补全`channel.c`溢出空间处理代码
+* 修复`channel->close`的bug
+* 修复协程socket`recv_package`的bug
+* 支持识别`form-data`编码以分号分隔的`boundary`
+* 更多高质量的单元测试, 更强的稳定性
+- 移除无用的时间轮算法
\ No newline at end of file
diff --git a/doc/1.5.4 - 4.1.2.md b/doc/1.5.4 - 4.1.2.md
new file mode 100644
index 0000000..77c4a18
--- /dev/null
+++ b/doc/1.5.4 - 4.1.2.md
@@ -0,0 +1,9 @@
+# 4.1.2
+
++ 增加`socket_hook`
+* 修复嵌套协程的BUG
+* 修复协程中退出时传入变量引用计数问题
+* 协程MySQL`query`, `prepare`, `execute` 默认不超时, 符合文档API描述
+* 协程MySQL事务操作禁止使用defer模式, 需开发者明确用途, 并发开启事务可用`query`代替
+* 修复mmap `MAP_FAILED` 返回值检测的问题
++ 增加PECL打包检测
\ No newline at end of file
diff --git a/doc/1.5.5 - 4.1.1.md b/doc/1.5.5 - 4.1.1.md
new file mode 100644
index 0000000..cf33f3e
--- /dev/null
+++ b/doc/1.5.5 - 4.1.1.md
@@ -0,0 +1,3 @@
+# 4.1.1
+
+- 仅修复了PECL打包缺失文件编译失败的问题
\ No newline at end of file
diff --git a/doc/1.5.6 - 4.1.0.md b/doc/1.5.6 - 4.1.0.md
new file mode 100644
index 0000000..9f8f012
--- /dev/null
+++ b/doc/1.5.6 - 4.1.0.md
@@ -0,0 +1,91 @@
+# 4.1.0
+
+重大新特性
+-----
+## 支持 Redis/PDO/MySQLi
+
+从`4.1.0`版本开始支持了对`PHP`原生`Redis`、`PDO`、`MySQLi`协程化的支持。
+
+可使用`Swoole\Runtime::enableCorotuine()`将普通的同步阻塞`Redis`、`PDO`、`MySQLi`操作变为协程调度的异步非阻塞`IO`
+
+```php
+Swoole\Runtime::enableCoroutine();
+
+go(function () {
+ $redis = new redis;
+ $retval = $redis->connect("127.0.0.1", 6379);
+ var_dump($retval, $redis->getLastError());
+ var_dump($redis->get("key"));
+ var_dump($redis->set("key", "value"));
+ $redis->close();
+});
+```
+
+## 协程跟踪
+
+新版本增加了两个方法用于跟踪协程运行。
+
+* `Coroutine::listCoroutines()`可遍历当前所有协程
+* `Coroutine::getBackTrace($cid)`可获取某个协程的函数调用栈
+
+```php
+function test1() {
+ test2();
+}
+
+function test2() {
+ while(true) {
+ co::sleep(10);
+ echo __FUNCTION__." \n";
+ }
+}
+
+$cid = go(function () {
+ test1();
+});
+
+go(function () use ($cid) {
+ while(true) {
+ echo "BackTrace[$cid]:\n-----------------------------------------------\n";
+ //返回数组,需要自行格式化输出
+ var_dump(co::getBackTrace($cid))."\n";
+ co::sleep(3);
+ }
+});
+```
+
+```shell
+BackTrace[1]:
+-----------------------------------------------
+#0 Swoole\Coroutine::sleep(10) called at [/home/htf/workspace/swoole/examples/coroutine/backtrace.php:8]
+#1 test2() called at [/home/htf/workspace/swoole/examples/coroutine/backtrace.php:3]
+#2 test1() called at [/home/htf/workspace/swoole/examples/coroutine/backtrace.php:14]
+```
+
+---
+
+## 其他修改
+
++ 重构 `Co\Channel` C底层代码为C++, 解决复杂场景的非预期结果, 实现高稳定
++ 重构 `Co\Http\Client` C底层代码为C++协程模式, 解决异步时序问题, 实现高稳定
++ 支持在协程和Server中使用`exit`, 此时将会抛出可捕获的`\Swoole\ExitException`异常
++ 移除所有迭代器(table/connection/coroutine_list)的PCRE依赖限制
++ 增加`open_websocket_close_frame`配置, 可以在onMessage事件中接收close帧
++ 废弃`Http\Response->gzip()`方法,改为使用`http_compression`配置项。底层会自动判断客户端传入的`Accept-Encoding`选择合适的压缩方法, 新增谷歌BR压缩支持
++ 增加`Co\Http\Client->addData()`方法,可将内存中的数据作为上传文件内容进行发送
++ `Solaris`系统支持
++ Http2支持`MAX_FRAME_SIZE`分帧发送和`MAX_HEADER_LIST_SIZE`处理, 客户端增加`isStreamExist`方法检测是否存在对应流
++ `swoole_http_response->status`增加`reason`参数
+* 修复MySQL prepare 中无符号参数使用了有符号值导致数值溢出的问题
+* 修复HTTP2的`onRequest`回调中没有协程的问题
+* 修复`tasking_num`某些特殊情况下变为`-1`的问题
+* 修复HTTP2-server的window-update帧构造错误
+* 修复所有PHP版本下的所有级别的编译warning
+* GCC版本小于4.8时将会产生编译错误
+* 修复MySQL使用prepare时未使用参数绑定导致的内存分配不断增长
+* 修复HTTP2重连时旧stream内存丢失泄露
+
+底层开发相关
+---
++ 统一文件命名 [#970](https://github.com/swoole/swoole-src/issues/970)
++ `Co\Http\Client`使用了`create_obj`和`free_obj`保证内存安全, 防止错误的PHP代码引发内存问题
\ No newline at end of file
diff --git a/doc/1.5.7 - 4.0.4.md b/doc/1.5.7 - 4.0.4.md
new file mode 100644
index 0000000..8767beb
--- /dev/null
+++ b/doc/1.5.7 - 4.0.4.md
@@ -0,0 +1,19 @@
+# 4.0.4
+
+* 修复了在SWOOLE_PROCESS极端情况下的一个[内核级别错误](https://github.com/swoole/swoole-src/issues/1864)
+* 修复`WebSocket`协程客户端接收超时关闭连接的问题
+* 修复`PHP`类继承扩展内置类未调用`parent::__construct`导致出现`crash`的问题
+* 底层禁止用户手动调用所有swoole类的析构`__destruct`方法, 避免`crash`
+* 修复上传过长文件名导致的`crash`
+* 完全修复编译时`HAVE_SOCKETS`不存在问题, 包括静态编译
+* 修复协程`suspend`和`resume`断言错误
+* `taskwait`支持协程调度,在协程内调用`taskwait`不会阻塞
+* 更完善的`HTTP2协议`支持, 可用于构建任意`Grpc客户端`
+* [Http2客户端的相关不兼容改动](https://wiki.swoole.com/wiki/page/964.html)
+* 完善`MacOS`下的`Signal`处理
+
+
+### 底层相关
+* 删除所有无用的PHP5兼容性代码, 大量精简了代码
+* 部署了完善的travis-ci自动化测试, 确保每一次提交都准确无误
+* 删除无用的timefd代码
\ No newline at end of file
diff --git a/doc/1.5.3 - 4.0.3.md b/doc/1.5.8 - 4.0.3.md
similarity index 100%
rename from doc/1.5.3 - 4.0.3.md
rename to doc/1.5.8 - 4.0.3.md
diff --git a/doc/1.5.2 - 4.0.2.md b/doc/1.5.9 - 4.0.2.md
similarity index 100%
rename from doc/1.5.2 - 4.0.2.md
rename to doc/1.5.9 - 4.0.2.md
diff --git "a/doc/1.6 - \345\220\221\344\270\213\344\270\215\345\205\274\345\256\271\346\224\271\345\212\250.md" "b/doc/1.6 - \345\220\221\344\270\213\344\270\215\345\205\274\345\256\271\346\224\271\345\212\250.md"
new file mode 100644
index 0000000..4e15984
--- /dev/null
+++ "b/doc/1.6 - \345\220\221\344\270\213\344\270\215\345\205\274\345\256\271\346\224\271\345\212\250.md"
@@ -0,0 +1,37 @@
+# 向下不兼容改动
+
+## 4.2.0
+彻底移除了异步`swoole_http2_client`
+
+## 4.0.4
+此版本开始, 异步`Swoole\Http2\Client` 将会触发 `E_DEPRECATED` 提示, 并在下个版本删除, 请使用 `Swoole\Coroutine\Http2\Client`来代替
+
+ `swoole_http2_response` 的 `body` 属性 重命名 为 `data`, 此修改是为了保证 `request` 和 `response` 两者的统一, 并且更符合HTTP2协议的帧类型名称.
+
+自该版本起, `Swoole\Coroutine\Http2\Client` 拥有了相对完整的HTTP2协议支持, 能满足企业级的生产环境应用需求, 如`grpc`, `etcd` 等, 所以关于HTTP2的一系列改动是非常必要的
+
+---
+
+## 4.0.3
+使`swoole_http2_response` 和 `swoole_http2_request` 保持一致, 所有属性名修改为复数形式, 涉及以下属性
+
+- `headers`
+- `cookies`
+
+---
+
+## 4.0.2
+> 由于底层实现过于复杂, 难以维护, 且用户经常对其使用产生误区, 故暂时删除以下API:
+
+- `Coroutine\Channel::select`
+
+但同时增加了`Coroutine\Channel->pop`方法的第二参数为`timeout`来满足开发需求
+
+
+## 4.0
+> 由于协程内核升级, 可以在任意函数任意地方调用协程, 无需做特殊处理, 故删除了以下API
+
+- `Coroutine::call_user_func`
+- `Coroutine::call_user_func_array`
+
+---
\ No newline at end of file
diff --git "a/doc/1.6 - \346\226\260\347\211\271\346\200\247\344\275\277\347\224\250.md" "b/doc/1.7 - \346\226\260\347\211\271\346\200\247\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/1.6 - \346\226\260\347\211\271\346\200\247\344\275\277\347\224\250.md"
rename to "doc/1.7 - \346\226\260\347\211\271\346\200\247\344\275\277\347\224\250.md"
diff --git "a/doc/1.6.1 - 2.1.2 \350\277\233\347\250\213\346\261\240\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md" "b/doc/1.7.1 - 2.1.2 \350\277\233\347\250\213\346\261\240\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/1.6.1 - 2.1.2 \350\277\233\347\250\213\346\261\240\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md"
rename to "doc/1.7.1 - 2.1.2 \350\277\233\347\250\213\346\261\240\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md"
diff --git "a/doc/1.6.10 - 1.7.4 SSL\351\232\247\351\201\223\345\212\240\345\257\206TCP-Server.md" "b/doc/1.7.10 - 1.7.4 SSL\351\232\247\351\201\223\345\212\240\345\257\206TCP-Server.md"
similarity index 100%
rename from "doc/1.6.10 - 1.7.4 SSL\351\232\247\351\201\223\345\212\240\345\257\206TCP-Server.md"
rename to "doc/1.7.10 - 1.7.4 SSL\351\232\247\351\201\223\345\212\240\345\257\206TCP-Server.md"
diff --git "a/doc/1.6.11 - 1.7.4 task\350\277\233\347\250\213\344\270\255\344\275\277\347\224\250\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md" "b/doc/1.7.11 - 1.7.4 task\350\277\233\347\250\213\344\270\255\344\275\277\347\224\250\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md"
similarity index 100%
rename from "doc/1.6.11 - 1.7.4 task\350\277\233\347\250\213\344\270\255\344\275\277\347\224\250\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md"
rename to "doc/1.7.11 - 1.7.4 task\350\277\233\347\250\213\344\270\255\344\275\277\347\224\250\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md"
diff --git "a/doc/1.6.12 - 1.7.3 \345\233\272\345\256\232\345\214\205\345\244\264+\345\214\205\344\275\223\345\215\217\350\256\256\350\207\252\345\212\250\345\210\206\345\214\205.md" "b/doc/1.7.12 - 1.7.3 \345\233\272\345\256\232\345\214\205\345\244\264+\345\214\205\344\275\223\345\215\217\350\256\256\350\207\252\345\212\250\345\210\206\345\214\205.md"
similarity index 100%
rename from "doc/1.6.12 - 1.7.3 \345\233\272\345\256\232\345\214\205\345\244\264+\345\214\205\344\275\223\345\215\217\350\256\256\350\207\252\345\212\250\345\210\206\345\214\205.md"
rename to "doc/1.7.12 - 1.7.3 \345\233\272\345\256\232\345\214\205\345\244\264+\345\214\205\344\275\223\345\215\217\350\256\256\350\207\252\345\212\250\345\210\206\345\214\205.md"
diff --git "a/doc/1.6.13 - 1.7.3 onTask\347\233\264\346\216\245return\345\217\226\344\273\243finish\345\207\275\346\225\260.md" "b/doc/1.7.13 - 1.7.3 onTask\347\233\264\346\216\245return\345\217\226\344\273\243finish\345\207\275\346\225\260.md"
similarity index 100%
rename from "doc/1.6.13 - 1.7.3 onTask\347\233\264\346\216\245return\345\217\226\344\273\243finish\345\207\275\346\225\260.md"
rename to "doc/1.7.13 - 1.7.3 onTask\347\233\264\346\216\245return\345\217\226\344\273\243finish\345\207\275\346\225\260.md"
diff --git "a/doc/1.6.14 - 1.7.2 swoole_process\345\244\232\350\277\233\347\250\213\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md" "b/doc/1.7.14 - 1.7.2 swoole_process\345\244\232\350\277\233\347\250\213\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/1.6.14 - 1.7.2 swoole_process\345\244\232\350\277\233\347\250\213\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md"
rename to "doc/1.7.14 - 1.7.2 swoole_process\345\244\232\350\277\233\347\250\213\346\250\241\345\235\227\347\232\204\344\275\277\347\224\250.md"
diff --git "a/doc/1.6.15 - 1.7.2 task\350\277\233\347\250\213\344\275\277\347\224\250\346\266\210\346\201\257\351\230\237\345\210\227.md" "b/doc/1.7.15 - 1.7.2 task\350\277\233\347\250\213\344\275\277\347\224\250\346\266\210\346\201\257\351\230\237\345\210\227.md"
similarity index 100%
rename from "doc/1.6.15 - 1.7.2 task\350\277\233\347\250\213\344\275\277\347\224\250\346\266\210\346\201\257\351\230\237\345\210\227.md"
rename to "doc/1.7.15 - 1.7.2 task\350\277\233\347\250\213\344\275\277\347\224\250\346\266\210\346\201\257\351\230\237\345\210\227.md"
diff --git "a/doc/1.6.2 - 1.9.24 \350\260\203\345\272\246\346\224\257\346\214\201 Stream \346\250\241\345\274\217.md" "b/doc/1.7.2 - 1.9.24 \350\260\203\345\272\246\346\224\257\346\214\201 Stream \346\250\241\345\274\217.md"
similarity index 91%
rename from "doc/1.6.2 - 1.9.24 \350\260\203\345\272\246\346\224\257\346\214\201 Stream \346\250\241\345\274\217.md"
rename to "doc/1.7.2 - 1.9.24 \350\260\203\345\272\246\346\224\257\346\214\201 Stream \346\250\241\345\274\217.md"
index 8ea71ce..4036141 100644
--- "a/doc/1.6.2 - 1.9.24 \350\260\203\345\272\246\346\224\257\346\214\201 Stream \346\250\241\345\274\217.md"
+++ "b/doc/1.7.2 - 1.9.24 \350\260\203\345\272\246\346\224\257\346\214\201 Stream \346\250\241\345\274\217.md"
@@ -1,6 +1,8 @@
# 1.9.24 调度支持 Stream 模式
-单连接并发的同步服务器一般使用`dispatch_mode = 3`调度请求分配到`Worker`进程,底层实现使用了忙闲识别方式。
+> 只适用于同步模式
+
+**单连接并发的同步服务器**一般使用`dispatch_mode = 3`调度请求分配到`Worker`进程,底层实现使用了忙闲识别方式。
* 当`Worker`进程接收到请求回调`onReceive`或`onRequest`时,将`Worker`进程的状态设置为`BUSY`,这时`Reactor`线程将不会再给当前的`Worker`进程分配新的请求
* 当`Worker`进程处理完当前的请求后,将状态设置为`IDLE`,这时`Reactor`线程将会继续给当前的`Worker`进程分配新请求
diff --git "a/doc/1.6.3 - 1.9.24 \345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\207\252\345\212\250\350\247\243\346\236\220\345\237\237\345\220\215.md" "b/doc/1.7.3 - 1.9.24 \345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\207\252\345\212\250\350\247\243\346\236\220\345\237\237\345\220\215.md"
similarity index 100%
rename from "doc/1.6.3 - 1.9.24 \345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\207\252\345\212\250\350\247\243\346\236\220\345\237\237\345\220\215.md"
rename to "doc/1.7.3 - 1.9.24 \345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\207\252\345\212\250\350\247\243\346\236\220\345\237\237\345\220\215.md"
diff --git "a/doc/1.6.4 - 1.9.17 \346\224\257\346\214\201\345\274\202\346\255\245\345\256\211\345\205\250\351\207\215\345\220\257\347\211\271\346\200\247.md" "b/doc/1.7.4 - 1.9.17 \346\224\257\346\214\201\345\274\202\346\255\245\345\256\211\345\205\250\351\207\215\345\220\257\347\211\271\346\200\247.md"
similarity index 100%
rename from "doc/1.6.4 - 1.9.17 \346\224\257\346\214\201\345\274\202\346\255\245\345\256\211\345\205\250\351\207\215\345\220\257\347\211\271\346\200\247.md"
rename to "doc/1.7.4 - 1.9.17 \346\224\257\346\214\201\345\274\202\346\255\245\345\256\211\345\205\250\351\207\215\345\220\257\347\211\271\346\200\247.md"
diff --git "a/doc/1.6.5 - 1.9.14 \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\266\205\346\227\266\346\234\272\345\210\266.md" "b/doc/1.7.5 - 1.9.14 \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\266\205\346\227\266\346\234\272\345\210\266.md"
similarity index 100%
rename from "doc/1.6.5 - 1.9.14 \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\266\205\346\227\266\346\234\272\345\210\266.md"
rename to "doc/1.7.5 - 1.9.14 \344\275\277\347\224\250\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257\350\266\205\346\227\266\346\234\272\345\210\266.md"
diff --git "a/doc/1.6.6 - 1.8.0 \344\275\277\347\224\250\345\206\205\347\275\256Http\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md" "b/doc/1.7.6 - 1.8.0 \344\275\277\347\224\250\345\206\205\347\275\256Http\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md"
similarity index 100%
rename from "doc/1.6.6 - 1.8.0 \344\275\277\347\224\250\345\206\205\347\275\256Http\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md"
rename to "doc/1.7.6 - 1.8.0 \344\275\277\347\224\250\345\206\205\347\275\256Http\345\274\202\346\255\245\345\256\242\346\210\267\347\253\257.md"
diff --git "a/doc/1.6.7 - 1.7.16 \344\275\277\347\224\250\350\277\255\344\273\243\345\231\250\351\201\215\345\216\206Server\346\211\200\346\234\211\350\277\236\346\216\245.md" "b/doc/1.7.7 - 1.7.16 \344\275\277\347\224\250\350\277\255\344\273\243\345\231\250\351\201\215\345\216\206Server\346\211\200\346\234\211\350\277\236\346\216\245.md"
similarity index 100%
rename from "doc/1.6.7 - 1.7.16 \344\275\277\347\224\250\350\277\255\344\273\243\345\231\250\351\201\215\345\216\206Server\346\211\200\346\234\211\350\277\236\346\216\245.md"
rename to "doc/1.7.7 - 1.7.16 \344\275\277\347\224\250\350\277\255\344\273\243\345\231\250\351\201\215\345\216\206Server\346\211\200\346\234\211\350\277\236\346\216\245.md"
diff --git "a/doc/1.6.8 - 1.7.5 \345\234\250Server\344\270\255\344\275\277\347\224\250swoole_table.md" "b/doc/1.7.8 - 1.7.5 \345\234\250Server\344\270\255\344\275\277\347\224\250swoole_table.md"
similarity index 100%
rename from "doc/1.6.8 - 1.7.5 \345\234\250Server\344\270\255\344\275\277\347\224\250swoole_table.md"
rename to "doc/1.7.8 - 1.7.5 \345\234\250Server\344\270\255\344\275\277\347\224\250swoole_table.md"
diff --git "a/doc/1.6.9 - 1.7.5 swoole_client\346\224\257\346\214\201sendfile\346\216\245\345\217\243.md" "b/doc/1.7.9 - 1.7.5 swoole_client\346\224\257\346\214\201sendfile\346\216\245\345\217\243.md"
similarity index 100%
rename from "doc/1.6.9 - 1.7.5 swoole_client\346\224\257\346\214\201sendfile\346\216\245\345\217\243.md"
rename to "doc/1.7.9 - 1.7.5 swoole_client\346\224\257\346\214\201sendfile\346\216\245\345\217\243.md"
diff --git "a/doc/1.7 - \351\241\271\347\233\256\350\267\257\347\272\277\345\233\276.md" "b/doc/1.8 - \351\241\271\347\233\256\350\267\257\347\272\277\345\233\276.md"
similarity index 100%
rename from "doc/1.7 - \351\241\271\347\233\256\350\267\257\347\272\277\345\233\276.md"
rename to "doc/1.8 - \351\241\271\347\233\256\350\267\257\347\272\277\345\233\276.md"
diff --git "a/doc/1.8 - php.ini\351\200\211\351\241\271.md" "b/doc/1.9 - php.ini\351\200\211\351\241\271.md"
similarity index 95%
rename from "doc/1.8 - php.ini\351\200\211\351\241\271.md"
rename to "doc/1.9 - php.ini\351\200\211\351\241\271.md"
index c257017..702132d 100644
--- "a/doc/1.8 - php.ini\351\200\211\351\241\271.md"
+++ "b/doc/1.9 - php.ini\351\200\211\351\241\271.md"
@@ -1,5 +1,9 @@
# php.ini选项
+swoole.enable_coroutine
+---
+`On`, `Off` 开关内置协程, 默认开启
+
swoole.aio_thread_num
----
设置`AIO`异步文件读写的线程数量,默认为`2`
diff --git "a/doc/10.1 - Process\357\274\217Pool::__construct.md" "b/doc/10.1 - Process\357\274\217Pool::__construct.md"
index 497fb02..2574a46 100644
--- "a/doc/10.1 - Process\357\274\217Pool::__construct.md"
+++ "b/doc/10.1 - Process\357\274\217Pool::__construct.md"
@@ -14,3 +14,20 @@ function Process\Pool::__construct(int $worker_num, int $ipc_type = 0, int $msgq
* 设置为`SWOOLE_IPC_SOCKET`表示使用`Socket`进行通信,需要使用`listen`方法指定监听的地址和端口
* 使用非`0`设置时,必须设置`onMessage`回调,`onWorkerStart`变更为可选
+
+消息队列
+------
+在使用`SWOOLE_IPC_MSGQUEUE`时可使用`sysvmsg`扩展提供的消息队列`API`向工作进程投递人任务。
+
+
+```php
+$q = msg_get_queue($key);
+foreach (range(1, 100) as $i) {
+ $data = json_encode(['data' => base64_encode(random_bytes(1024)), 'id' => uniqid(), 'index' => $i,]);
+ msg_send($q, $i, $data, false);
+}
+```
+
+* 必须传入`Pool`创建时使用的`key`
+* 底层不支持`msg_send`的第二个参数`mtype`,请传入任意非`0`值
+
diff --git "a/doc/10.6 - Process\357\274\217Pool->getProcess.md" "b/doc/10.6 - Process\357\274\217Pool->getProcess.md"
new file mode 100644
index 0000000..dc920ee
--- /dev/null
+++ "b/doc/10.6 - Process\357\274\217Pool->getProcess.md"
@@ -0,0 +1,30 @@
+# Process\Pool->getProcess
+
+获取当前工作进程对象。返回`Swoole\Process`对象。
+> 需要 swoole 版本 >= 4.2.0
+
+```php
+function Process\Pool->getProcess() : Process;
+```
+
+* 必须在`start`之后,在工作进程的`onWorkerStart`或其他回调函数中调用
+* 返回的`Process`对象是单例模式,在工作进程中重复调用`getProcess()`将返回同一个对象
+
+
+使用实例
+----
+```php
+$workerNum = 10;
+$pool = new Swoole\Process\Pool($workerNum);
+
+$pool->on("WorkerStart", function ($pool, $workerId) {
+ $process = $pool->getProcess();
+ $process->exec("/bin/sh", ["ls", '-l']);
+});
+
+$pool->on("WorkerStop", function ($pool, $workerId) {
+ echo "Worker#{$workerId} is stopped\n";
+});
+
+$pool->start();
+```
\ No newline at end of file
diff --git "a/doc/12.14 - \344\275\277\347\224\250jemalloc\344\274\230\345\214\226swoole\345\206\205\345\255\230\345\210\206\351\205\215\346\200\247\350\203\275.md" "b/doc/12.14 - \344\275\277\347\224\250jemalloc\344\274\230\345\214\226swoole\345\206\205\345\255\230\345\210\206\351\205\215\346\200\247\350\203\275.md"
index 07a8648..f812503 100644
--- "a/doc/12.14 - \344\275\277\347\224\250jemalloc\344\274\230\345\214\226swoole\345\206\205\345\255\230\345\210\206\351\205\215\346\200\247\350\203\275.md"
+++ "b/doc/12.14 - \344\275\277\347\224\250jemalloc\344\274\230\345\214\226swoole\345\206\205\345\255\230\345\210\206\351\205\215\346\200\247\350\203\275.md"
@@ -1,5 +1,9 @@
# 使用jemalloc优化swoole内存分配性能
+> 现已不建议使用jemalloc, 可能会降低程序稳定性
+
+> 建议使用标准的malloc和PHP官方提供的emalloc (默认)
+
关于jemalloc
----
jemalloc是一个比glibc malloc更高效的内存池技术,在Facebook公司被大量使用,在FreeBSD和FireFox项目中使用了jemalloc作为默认的内存管理器。使用jemalloc可以使程序的内存管理性能提升,减少内存碎片。
diff --git "a/doc/12.23 - Windows\347\274\226\350\257\221.md" "b/doc/12.23 - Windows\347\274\226\350\257\221.md"
new file mode 100644
index 0000000..39f1ea3
--- /dev/null
+++ "b/doc/12.23 - Windows\347\274\226\350\257\221.md"
@@ -0,0 +1,11 @@
+# Windows编译
+
+编译PHP
+----
+参照 [PHP官方文档](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2)
+
+配置参数
+----
+```shell
+configure "--enable-swoole=shared --disable-all --enable-cli"
+```
\ No newline at end of file
diff --git a/doc/13.1.2 - swoole_version.md b/doc/13.1.2 - swoole_version.md
index f76519b..5df4ca5 100644
--- a/doc/13.1.2 - swoole_version.md
+++ b/doc/13.1.2 - swoole_version.md
@@ -1,6 +1,36 @@
# swoole_version
获取swoole扩展的版本号,如1.6.10
+
+函数原型
+---
+
```php
string swoole_version();
```
+
+参数
+---
+无
+
+返回值
+---
+返回当前执行的PHP安装的Swoole扩展版本
+
+使用示例
+---
+```php
+ "192.168.1.100");
+array swoole_get_local_ip();
```
+返回值
+---
+返回当前机器的所有网络接口的IP地址
+
+使用示例
+---
+```php
+ 10.10.28.228
+ [br-1e72ecd47449] => 172.20.0.1
+ [docker0] => 172.17.0.1
+)
+**/
+```
+
+注意事项
+---
* 目前只返回IPv4地址,返回结果会过滤掉本地loop地址127.0.0.1。
* 结果数组是以interface名称为key的关联数组。比如 array("eth0" => "192.168.1.100")
diff --git "a/doc/13.9 - \351\231\204\345\275\225\357\274\232strace\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md" "b/doc/13.10 - \351\231\204\345\275\225\357\274\232strace\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/13.9 - \351\231\204\345\275\225\357\274\232strace\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
rename to "doc/13.10 - \351\231\204\345\275\225\357\274\232strace\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
diff --git "a/doc/13.10 - \351\231\204\345\275\225\357\274\232gdb\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md" "b/doc/13.11 - \351\231\204\345\275\225\357\274\232gdb\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/13.10 - \351\231\204\345\275\225\357\274\232gdb\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
rename to "doc/13.11 - \351\231\204\345\275\225\357\274\232gdb\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
diff --git "a/doc/13.11 - \351\231\204\345\275\225\357\274\232lsof\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md" "b/doc/13.12 - \351\231\204\345\275\225\357\274\232lsof\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/13.11 - \351\231\204\345\275\225\357\274\232lsof\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
rename to "doc/13.12 - \351\231\204\345\275\225\357\274\232lsof\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
diff --git "a/doc/13.12 - \351\231\204\345\275\225\357\274\232perf\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md" "b/doc/13.13 - \351\231\204\345\275\225\357\274\232perf\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/13.12 - \351\231\204\345\275\225\357\274\232perf\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
rename to "doc/13.13 - \351\231\204\345\275\225\357\274\232perf\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
diff --git "a/doc/13.13 - \351\231\204\345\275\225\357\274\232\347\274\226\350\257\221PHP\346\211\251\345\261\225\347\232\204\347\233\270\345\205\263\345\267\245\345\205\267.md" "b/doc/13.14 - \351\231\204\345\275\225\357\274\232\347\274\226\350\257\221PHP\346\211\251\345\261\225\347\232\204\347\233\270\345\205\263\345\267\245\345\205\267.md"
similarity index 100%
rename from "doc/13.13 - \351\231\204\345\275\225\357\274\232\347\274\226\350\257\221PHP\346\211\251\345\261\225\347\232\204\347\233\270\345\205\263\345\267\245\345\205\267.md"
rename to "doc/13.14 - \351\231\204\345\275\225\357\274\232\347\274\226\350\257\221PHP\346\211\251\345\261\225\347\232\204\347\233\270\345\205\263\345\267\245\345\205\267.md"
diff --git "a/doc/13.14 - \345\244\207\347\224\250\357\274\232\345\267\262\347\247\273\351\231\244\347\232\204\345\216\206\345\217\262\347\211\271\346\200\247.md" "b/doc/13.15 - \345\244\207\347\224\250\357\274\232\345\267\262\347\247\273\351\231\244\347\232\204\345\216\206\345\217\262\347\211\271\346\200\247.md"
similarity index 100%
rename from "doc/13.14 - \345\244\207\347\224\250\357\274\232\345\267\262\347\247\273\351\231\244\347\232\204\345\216\206\345\217\262\347\211\271\346\200\247.md"
rename to "doc/13.15 - \345\244\207\347\224\250\357\274\232\345\267\262\347\247\273\351\231\244\347\232\204\345\216\206\345\217\262\347\211\271\346\200\247.md"
diff --git a/doc/13.14.1 - swoole_server->handler.md b/doc/13.15.1 - swoole_server->handler.md
similarity index 100%
rename from doc/13.14.1 - swoole_server->handler.md
rename to doc/13.15.1 - swoole_server->handler.md
diff --git a/doc/13.14.10 - onMasterConnect.md b/doc/13.15.10 - onMasterConnect.md
similarity index 100%
rename from doc/13.14.10 - onMasterConnect.md
rename to doc/13.15.10 - onMasterConnect.md
diff --git a/doc/13.14.11 - onMasterClose.md b/doc/13.15.11 - onMasterClose.md
similarity index 100%
rename from doc/13.14.11 - onMasterClose.md
rename to doc/13.15.11 - onMasterClose.md
diff --git "a/doc/13.14.12 - Nginx\357\274\217Golang\357\274\217Swoole\357\274\217Node.js\347\232\204\346\200\247\350\203\275\345\257\271\346\257\224.md" "b/doc/13.15.12 - Nginx\357\274\217Golang\357\274\217Swoole\357\274\217Node.js\347\232\204\346\200\247\350\203\275\345\257\271\346\257\224.md"
similarity index 100%
rename from "doc/13.14.12 - Nginx\357\274\217Golang\357\274\217Swoole\357\274\217Node.js\347\232\204\346\200\247\350\203\275\345\257\271\346\257\224.md"
rename to "doc/13.15.12 - Nginx\357\274\217Golang\357\274\217Swoole\357\274\217Node.js\347\232\204\346\200\247\350\203\275\345\257\271\346\257\224.md"
diff --git a/doc/13.14.13 - Coroutine::call_user_func.md b/doc/13.15.13 - Coroutine::call_user_func.md
similarity index 100%
rename from doc/13.14.13 - Coroutine::call_user_func.md
rename to doc/13.15.13 - Coroutine::call_user_func.md
diff --git a/doc/13.14.14 - Coroutine::call_user_func_array.md b/doc/13.15.14 - Coroutine::call_user_func_array.md
similarity index 100%
rename from doc/13.14.14 - Coroutine::call_user_func_array.md
rename to doc/13.15.14 - Coroutine::call_user_func_array.md
diff --git "a/doc/4.2.6 - Coroutine\357\274\217Channel::select.md" "b/doc/13.15.15 - Coroutine\357\274\217Channel::select.md"
similarity index 88%
rename from "doc/4.2.6 - Coroutine\357\274\217Channel::select.md"
rename to "doc/13.15.15 - Coroutine\357\274\217Channel::select.md"
index c525b02..aa88cbc 100644
--- "a/doc/4.2.6 - Coroutine\357\274\217Channel::select.md"
+++ "b/doc/13.15.15 - Coroutine\357\274\217Channel::select.md"
@@ -1,5 +1,11 @@
# Coroutine\Channel::select
+废弃
+----
+```
+此方法存在安全问题,已废弃
+```
+
通道读写检测。类似于`socket_select`和`stream_select`可以检测`channel`是否可进行读写。
原型
@@ -23,6 +29,9 @@ function Coroutine\Channel::select(array &$read, array &$write, float $timeout =
* 成功返回`true`,底层会修改`$read`、`$write`数组,`$read`和`$write`中的元素,即是可读或可写的`channel`
* 超时或传入的参数错误,如`$read`和`$write`中有非`channel`对象,底层返回`false`
+注意事项
+----
+早期版本中`Coroutine\Channel`由于存在一些问题,在`Swoole4.0.3`版本重构并废弃了 `Coroutine\Channel::select` 方法。所以在`Swoole4.0.3`以上的版本请使用`channel->pop($timeout)`替代。
fibonacci 实例
----
diff --git a/doc/13.14.2 - task_worker_max.md b/doc/13.15.2 - task_worker_max.md
similarity index 100%
rename from doc/13.14.2 - task_worker_max.md
rename to doc/13.15.2 - task_worker_max.md
diff --git a/doc/13.14.3 - swoole_server->addtimer.md b/doc/13.15.3 - swoole_server->addtimer.md
similarity index 100%
rename from doc/13.14.3 - swoole_server->addtimer.md
rename to doc/13.15.3 - swoole_server->addtimer.md
diff --git a/doc/13.14.4 - swoole_server->deltimer.md b/doc/13.15.4 - swoole_server->deltimer.md
similarity index 100%
rename from doc/13.14.4 - swoole_server->deltimer.md
rename to doc/13.15.4 - swoole_server->deltimer.md
diff --git a/doc/13.14.5 - onTimer.md b/doc/13.15.5 - onTimer.md
similarity index 100%
rename from doc/13.14.5 - onTimer.md
rename to doc/13.15.5 - onTimer.md
diff --git a/doc/13.14.6 - swoole_timer_add.md b/doc/13.15.6 - swoole_timer_add.md
similarity index 100%
rename from doc/13.14.6 - swoole_timer_add.md
rename to doc/13.15.6 - swoole_timer_add.md
diff --git a/doc/13.14.7 - swoole_timer_del.md b/doc/13.15.7 - swoole_timer_del.md
similarity index 100%
rename from doc/13.14.7 - swoole_timer_del.md
rename to doc/13.15.7 - swoole_timer_del.md
diff --git a/doc/13.14.8 - swoole_get_mysqli_sock.md b/doc/13.15.8 - swoole_get_mysqli_sock.md
similarity index 100%
rename from doc/13.14.8 - swoole_get_mysqli_sock.md
rename to doc/13.15.8 - swoole_get_mysqli_sock.md
diff --git a/doc/13.14.9 - swoole_mysql_query.md b/doc/13.15.9 - swoole_mysql_query.md
similarity index 100%
rename from doc/13.14.9 - swoole_mysql_query.md
rename to doc/13.15.9 - swoole_mysql_query.md
diff --git "a/doc/13.15 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2101.x\357\274\211.md" "b/doc/13.16 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2101.x\357\274\211.md"
similarity index 100%
rename from "doc/13.15 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2101.x\357\274\211.md"
rename to "doc/13.16 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2101.x\357\274\211.md"
diff --git a/doc/13.15.1 - 1.10.3.md b/doc/13.16.1 - 1.10.3.md
similarity index 100%
rename from doc/13.15.1 - 1.10.3.md
rename to doc/13.16.1 - 1.10.3.md
diff --git a/doc/13.15.10 - 1.9.16.md b/doc/13.16.10 - 1.9.16.md
similarity index 100%
rename from doc/13.15.10 - 1.9.16.md
rename to doc/13.16.10 - 1.9.16.md
diff --git a/doc/13.15.11 - 1.9.15.md b/doc/13.16.11 - 1.9.15.md
similarity index 100%
rename from doc/13.15.11 - 1.9.15.md
rename to doc/13.16.11 - 1.9.15.md
diff --git a/doc/13.15.12 - 1.9.14.md b/doc/13.16.12 - 1.9.14.md
similarity index 100%
rename from doc/13.15.12 - 1.9.14.md
rename to doc/13.16.12 - 1.9.14.md
diff --git a/doc/13.15.13 - 1.9.12.md b/doc/13.16.13 - 1.9.12.md
similarity index 100%
rename from doc/13.15.13 - 1.9.12.md
rename to doc/13.16.13 - 1.9.12.md
diff --git a/doc/13.15.14 - 1.9.11.md b/doc/13.16.14 - 1.9.11.md
similarity index 100%
rename from doc/13.15.14 - 1.9.11.md
rename to doc/13.16.14 - 1.9.11.md
diff --git a/doc/13.15.15 - 1.9.9.md b/doc/13.16.15 - 1.9.9.md
similarity index 100%
rename from doc/13.15.15 - 1.9.9.md
rename to doc/13.16.15 - 1.9.9.md
diff --git a/doc/13.15.16 - 1.9.7.md b/doc/13.16.16 - 1.9.7.md
similarity index 100%
rename from doc/13.15.16 - 1.9.7.md
rename to doc/13.16.16 - 1.9.7.md
diff --git a/doc/13.15.17 - 1.9.6.md b/doc/13.16.17 - 1.9.6.md
similarity index 100%
rename from doc/13.15.17 - 1.9.6.md
rename to doc/13.16.17 - 1.9.6.md
diff --git a/doc/13.15.18 - 1.9.5.md b/doc/13.16.18 - 1.9.5.md
similarity index 100%
rename from doc/13.15.18 - 1.9.5.md
rename to doc/13.16.18 - 1.9.5.md
diff --git a/doc/13.15.19 - 1.9.4.md b/doc/13.16.19 - 1.9.4.md
similarity index 100%
rename from doc/13.15.19 - 1.9.4.md
rename to doc/13.16.19 - 1.9.4.md
diff --git a/doc/13.15.2 - 1.10.2.md b/doc/13.16.2 - 1.10.2.md
similarity index 100%
rename from doc/13.15.2 - 1.10.2.md
rename to doc/13.16.2 - 1.10.2.md
diff --git a/doc/13.15.20 - 1.9.3.md b/doc/13.16.20 - 1.9.3.md
similarity index 100%
rename from doc/13.15.20 - 1.9.3.md
rename to doc/13.16.20 - 1.9.3.md
diff --git a/doc/13.15.21 - 1.9.2.md b/doc/13.16.21 - 1.9.2.md
similarity index 100%
rename from doc/13.15.21 - 1.9.2.md
rename to doc/13.16.21 - 1.9.2.md
diff --git a/doc/13.15.22 - 1.9.1.md b/doc/13.16.22 - 1.9.1.md
similarity index 100%
rename from doc/13.15.22 - 1.9.1.md
rename to doc/13.16.22 - 1.9.1.md
diff --git a/doc/13.15.23 - 1.9.0.md b/doc/13.16.23 - 1.9.0.md
similarity index 100%
rename from doc/13.15.23 - 1.9.0.md
rename to doc/13.16.23 - 1.9.0.md
diff --git a/doc/13.15.24 - 1.8.13.md b/doc/13.16.24 - 1.8.13.md
similarity index 100%
rename from doc/13.15.24 - 1.8.13.md
rename to doc/13.16.24 - 1.8.13.md
diff --git a/doc/13.15.25 - 1.8.12.md b/doc/13.16.25 - 1.8.12.md
similarity index 100%
rename from doc/13.15.25 - 1.8.12.md
rename to doc/13.16.25 - 1.8.12.md
diff --git a/doc/13.15.26 - 1.8.11.md b/doc/13.16.26 - 1.8.11.md
similarity index 100%
rename from doc/13.15.26 - 1.8.11.md
rename to doc/13.16.26 - 1.8.11.md
diff --git a/doc/13.15.27 - 1.8.10.md b/doc/13.16.27 - 1.8.10.md
similarity index 100%
rename from doc/13.15.27 - 1.8.10.md
rename to doc/13.16.27 - 1.8.10.md
diff --git a/doc/13.15.28 - 1.8.9.md b/doc/13.16.28 - 1.8.9.md
similarity index 100%
rename from doc/13.15.28 - 1.8.9.md
rename to doc/13.16.28 - 1.8.9.md
diff --git a/doc/13.15.29 - 1.8.8.md b/doc/13.16.29 - 1.8.8.md
similarity index 100%
rename from doc/13.15.29 - 1.8.8.md
rename to doc/13.16.29 - 1.8.8.md
diff --git a/doc/13.15.3 - 1.10.1.md b/doc/13.16.3 - 1.10.1.md
similarity index 100%
rename from doc/13.15.3 - 1.10.1.md
rename to doc/13.16.3 - 1.10.1.md
diff --git a/doc/13.15.30 - 1.8.7.md b/doc/13.16.30 - 1.8.7.md
similarity index 100%
rename from doc/13.15.30 - 1.8.7.md
rename to doc/13.16.30 - 1.8.7.md
diff --git a/doc/13.15.31 - 1.8.6.md b/doc/13.16.31 - 1.8.6.md
similarity index 100%
rename from doc/13.15.31 - 1.8.6.md
rename to doc/13.16.31 - 1.8.6.md
diff --git a/doc/13.15.32 - 1.8.5.md b/doc/13.16.32 - 1.8.5.md
similarity index 100%
rename from doc/13.15.32 - 1.8.5.md
rename to doc/13.16.32 - 1.8.5.md
diff --git a/doc/13.15.33 - 1.8.4.md b/doc/13.16.33 - 1.8.4.md
similarity index 100%
rename from doc/13.15.33 - 1.8.4.md
rename to doc/13.16.33 - 1.8.4.md
diff --git a/doc/13.15.34 - 1.8.3.md b/doc/13.16.34 - 1.8.3.md
similarity index 100%
rename from doc/13.15.34 - 1.8.3.md
rename to doc/13.16.34 - 1.8.3.md
diff --git a/doc/13.15.35 - 1.8.2.md b/doc/13.16.35 - 1.8.2.md
similarity index 100%
rename from doc/13.15.35 - 1.8.2.md
rename to doc/13.16.35 - 1.8.2.md
diff --git a/doc/13.15.36 - 1.8.1.md b/doc/13.16.36 - 1.8.1.md
similarity index 100%
rename from doc/13.15.36 - 1.8.1.md
rename to doc/13.16.36 - 1.8.1.md
diff --git a/doc/13.15.37 - 1.8.0.md b/doc/13.16.37 - 1.8.0.md
similarity index 100%
rename from doc/13.15.37 - 1.8.0.md
rename to doc/13.16.37 - 1.8.0.md
diff --git a/doc/13.15.38 - 1.7.22.md b/doc/13.16.38 - 1.7.22.md
similarity index 100%
rename from doc/13.15.38 - 1.7.22.md
rename to doc/13.16.38 - 1.7.22.md
diff --git a/doc/13.15.39 - 1.7.21.md b/doc/13.16.39 - 1.7.21.md
similarity index 100%
rename from doc/13.15.39 - 1.7.21.md
rename to doc/13.16.39 - 1.7.21.md
diff --git a/doc/13.15.4 - 1.10.0.md b/doc/13.16.4 - 1.10.0.md
similarity index 100%
rename from doc/13.15.4 - 1.10.0.md
rename to doc/13.16.4 - 1.10.0.md
diff --git a/doc/13.15.40 - 1.7.20.md b/doc/13.16.40 - 1.7.20.md
similarity index 100%
rename from doc/13.15.40 - 1.7.20.md
rename to doc/13.16.40 - 1.7.20.md
diff --git a/doc/13.15.41 - 1.7.19.md b/doc/13.16.41 - 1.7.19.md
similarity index 100%
rename from doc/13.15.41 - 1.7.19.md
rename to doc/13.16.41 - 1.7.19.md
diff --git a/doc/13.15.42 - 1.7.18.md b/doc/13.16.42 - 1.7.18.md
similarity index 100%
rename from doc/13.15.42 - 1.7.18.md
rename to doc/13.16.42 - 1.7.18.md
diff --git a/doc/13.15.43 - 1.7.17.md b/doc/13.16.43 - 1.7.17.md
similarity index 100%
rename from doc/13.15.43 - 1.7.17.md
rename to doc/13.16.43 - 1.7.17.md
diff --git a/doc/13.15.44 - 1.7.16.md b/doc/13.16.44 - 1.7.16.md
similarity index 100%
rename from doc/13.15.44 - 1.7.16.md
rename to doc/13.16.44 - 1.7.16.md
diff --git a/doc/13.15.45 - 1.7.15.md b/doc/13.16.45 - 1.7.15.md
similarity index 100%
rename from doc/13.15.45 - 1.7.15.md
rename to doc/13.16.45 - 1.7.15.md
diff --git a/doc/13.15.46 - 1.7.14.md b/doc/13.16.46 - 1.7.14.md
similarity index 100%
rename from doc/13.15.46 - 1.7.14.md
rename to doc/13.16.46 - 1.7.14.md
diff --git a/doc/13.15.47 - 1.7.13.md b/doc/13.16.47 - 1.7.13.md
similarity index 100%
rename from doc/13.15.47 - 1.7.13.md
rename to doc/13.16.47 - 1.7.13.md
diff --git a/doc/13.15.48 - 1.7.12.md b/doc/13.16.48 - 1.7.12.md
similarity index 100%
rename from doc/13.15.48 - 1.7.12.md
rename to doc/13.16.48 - 1.7.12.md
diff --git a/doc/13.15.49 - 1.7.11.md b/doc/13.16.49 - 1.7.11.md
similarity index 100%
rename from doc/13.15.49 - 1.7.11.md
rename to doc/13.16.49 - 1.7.11.md
diff --git a/doc/13.15.5 - 1.9.23.md b/doc/13.16.5 - 1.9.23.md
similarity index 100%
rename from doc/13.15.5 - 1.9.23.md
rename to doc/13.16.5 - 1.9.23.md
diff --git a/doc/13.15.50 - 1.7.10.md b/doc/13.16.50 - 1.7.10.md
similarity index 100%
rename from doc/13.15.50 - 1.7.10.md
rename to doc/13.16.50 - 1.7.10.md
diff --git a/doc/13.15.51 - 1.7.9.md b/doc/13.16.51 - 1.7.9.md
similarity index 100%
rename from doc/13.15.51 - 1.7.9.md
rename to doc/13.16.51 - 1.7.9.md
diff --git a/doc/13.15.52 - 1.7.8.md b/doc/13.16.52 - 1.7.8.md
similarity index 100%
rename from doc/13.15.52 - 1.7.8.md
rename to doc/13.16.52 - 1.7.8.md
diff --git a/doc/13.15.53 - 1.7.7.md b/doc/13.16.53 - 1.7.7.md
similarity index 100%
rename from doc/13.15.53 - 1.7.7.md
rename to doc/13.16.53 - 1.7.7.md
diff --git a/doc/13.15.54 - 1.7.6.md b/doc/13.16.54 - 1.7.6.md
similarity index 100%
rename from doc/13.15.54 - 1.7.6.md
rename to doc/13.16.54 - 1.7.6.md
diff --git a/doc/13.15.55 - 1.7.5.md b/doc/13.16.55 - 1.7.5.md
similarity index 100%
rename from doc/13.15.55 - 1.7.5.md
rename to doc/13.16.55 - 1.7.5.md
diff --git a/doc/13.15.56 - v1.5.md b/doc/13.16.56 - v1.5.md
similarity index 100%
rename from doc/13.15.56 - v1.5.md
rename to doc/13.16.56 - v1.5.md
diff --git a/doc/13.15.57 - v1.6.md b/doc/13.16.57 - v1.6.md
similarity index 100%
rename from doc/13.15.57 - v1.6.md
rename to doc/13.16.57 - v1.6.md
diff --git a/doc/13.15.58 - v1.7.md b/doc/13.16.58 - v1.7.md
similarity index 100%
rename from doc/13.15.58 - v1.7.md
rename to doc/13.16.58 - v1.7.md
diff --git a/doc/13.15.6 - 1.9.22.md b/doc/13.16.6 - 1.9.22.md
similarity index 100%
rename from doc/13.15.6 - 1.9.22.md
rename to doc/13.16.6 - 1.9.22.md
diff --git a/doc/13.15.7 - 1.9.19.md b/doc/13.16.7 - 1.9.19.md
similarity index 100%
rename from doc/13.15.7 - 1.9.19.md
rename to doc/13.16.7 - 1.9.19.md
diff --git a/doc/13.15.8 - 1.9.18.md b/doc/13.16.8 - 1.9.18.md
similarity index 100%
rename from doc/13.15.8 - 1.9.18.md
rename to doc/13.16.8 - 1.9.18.md
diff --git a/doc/13.15.9 - 1.9.17.md b/doc/13.16.9 - 1.9.17.md
similarity index 100%
rename from doc/13.15.9 - 1.9.17.md
rename to doc/13.16.9 - 1.9.17.md
diff --git "a/doc/13.16 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2102.x\357\274\211.md" "b/doc/13.17 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2102.x\357\274\211.md"
similarity index 100%
rename from "doc/13.16 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2102.x\357\274\211.md"
rename to "doc/13.17 - \345\216\206\345\217\262\357\274\232\347\211\210\346\234\254\346\233\264\346\226\260\350\256\260\345\275\225\357\274\2102.x\357\274\211.md"
diff --git a/doc/13.16.1 - 2.0.1-Alpha.md b/doc/13.17.1 - 2.0.1-Alpha.md
similarity index 100%
rename from doc/13.16.1 - 2.0.1-Alpha.md
rename to doc/13.17.1 - 2.0.1-Alpha.md
diff --git a/doc/13.16.10 - 2.1.2.md b/doc/13.17.10 - 2.1.2.md
similarity index 100%
rename from doc/13.16.10 - 2.1.2.md
rename to doc/13.17.10 - 2.1.2.md
diff --git a/doc/13.16.11 - 2.2.0.md b/doc/13.17.11 - 2.2.0.md
similarity index 100%
rename from doc/13.16.11 - 2.2.0.md
rename to doc/13.17.11 - 2.2.0.md
diff --git a/doc/13.16.12 - 3.0.0.md b/doc/13.17.12 - 3.0.0.md
similarity index 100%
rename from doc/13.16.12 - 3.0.0.md
rename to doc/13.17.12 - 3.0.0.md
diff --git a/doc/13.16.2 - 2.0.5.md b/doc/13.17.2 - 2.0.5.md
similarity index 100%
rename from doc/13.16.2 - 2.0.5.md
rename to doc/13.17.2 - 2.0.5.md
diff --git a/doc/13.16.3 - 2.0.9.md b/doc/13.17.3 - 2.0.9.md
similarity index 100%
rename from doc/13.16.3 - 2.0.9.md
rename to doc/13.17.3 - 2.0.9.md
diff --git a/doc/13.16.4 - 1.9.21.md b/doc/13.17.4 - 1.9.21.md
similarity index 100%
rename from doc/13.16.4 - 1.9.21.md
rename to doc/13.17.4 - 1.9.21.md
diff --git a/doc/13.16.5 - 2.0.10.md b/doc/13.17.5 - 2.0.10.md
similarity index 100%
rename from doc/13.16.5 - 2.0.10.md
rename to doc/13.17.5 - 2.0.10.md
diff --git a/doc/13.16.6 - 2.0.11.md b/doc/13.17.6 - 2.0.11.md
similarity index 100%
rename from doc/13.16.6 - 2.0.11.md
rename to doc/13.17.6 - 2.0.11.md
diff --git a/doc/13.16.7 - 2.0.12.md b/doc/13.17.7 - 2.0.12.md
similarity index 100%
rename from doc/13.16.7 - 2.0.12.md
rename to doc/13.17.7 - 2.0.12.md
diff --git a/doc/13.16.8 - 2.0.13.md b/doc/13.17.8 - 2.0.13.md
similarity index 100%
rename from doc/13.16.8 - 2.0.13.md
rename to doc/13.17.8 - 2.0.13.md
diff --git a/doc/13.16.9 - 2.1.1.md b/doc/13.17.9 - 2.1.1.md
similarity index 100%
rename from doc/13.16.9 - 2.1.1.md
rename to doc/13.17.9 - 2.1.1.md
diff --git "a/doc/13.19 - \345\217\202\344\270\216\345\274\200\346\272\220\351\241\271\347\233\256\346\214\207\345\274\225.md" "b/doc/13.20 - \345\217\202\344\270\216\345\274\200\346\272\220\351\241\271\347\233\256\346\214\207\345\274\225.md"
similarity index 100%
rename from "doc/13.19 - \345\217\202\344\270\216\345\274\200\346\272\220\351\241\271\347\233\256\346\214\207\345\274\225.md"
rename to "doc/13.20 - \345\217\202\344\270\216\345\274\200\346\272\220\351\241\271\347\233\256\346\214\207\345\274\225.md"
diff --git "a/doc/13.3 - Swoole\346\212\200\346\234\257\344\274\232\350\256\256.md" "b/doc/13.3 - Swoole\346\212\200\346\234\257\344\274\232\350\256\256.md"
new file mode 100644
index 0000000..6c0849e
--- /dev/null
+++ "b/doc/13.3 - Swoole\346\212\200\346\234\257\344\274\232\350\256\256.md"
@@ -0,0 +1,18 @@
+# Swoole技术会议
+
+
+10.27 杭州 CNCC(中国计算机大会)
+----
+- 分享嘉宾:韩天峰-Rango
+- 分享主题:Swoole4 基于协程+通道实现全新的 PHP CSP 编程
+- 大会网址:
+
+![](https://www.swoole.com/static/uploads/wiki/201810/10/686150903746.png)
+
+![](https://www.swoole.com/static/uploads/wiki/201810/10/686230789001.png)
+
+更多
+-----
+```
+请编辑本页,添加更多会议信息。请按照会议举办日期降序排列。务必包含会议的网址`URL`、城市、日期三项信息。
+```
\ No newline at end of file
diff --git "a/doc/13.3 - \346\215\220\350\265\240Swoole\351\241\271\347\233\256.md" "b/doc/13.4 - \346\215\220\350\265\240Swoole\351\241\271\347\233\256.md"
similarity index 98%
rename from "doc/13.3 - \346\215\220\350\265\240Swoole\351\241\271\347\233\256.md"
rename to "doc/13.4 - \346\215\220\350\265\240Swoole\351\241\271\347\233\256.md"
index 893551f..0548077 100644
--- "a/doc/13.3 - \346\215\220\350\265\240Swoole\351\241\271\347\233\256.md"
+++ "b/doc/13.4 - \346\215\220\350\265\240Swoole\351\241\271\347\233\256.md"
@@ -126,5 +126,6 @@
100.00 | 黄仁运 657***@qq.com | - | 支付宝 |
27.00 | 周曦 336***@qq.com | - | 支付宝 |
100.00 | 贺晶新 671***@qq.com | - | 支付宝 |
+66.66 | twosee tw***@qq.com | 已把本人贡献给swoole | 开源中国 |
diff --git "a/doc/13.4 - \345\212\240\345\205\245Swoole\345\274\200\345\217\221\347\273\204.md" "b/doc/13.5 - \345\212\240\345\205\245Swoole\345\274\200\345\217\221\347\273\204.md"
similarity index 92%
rename from "doc/13.4 - \345\212\240\345\205\245Swoole\345\274\200\345\217\221\347\273\204.md"
rename to "doc/13.5 - \345\212\240\345\205\245Swoole\345\274\200\345\217\221\347\273\204.md"
index 0d684c0..fa1cec4 100644
--- "a/doc/13.4 - \345\212\240\345\205\245Swoole\345\274\200\345\217\221\347\273\204.md"
+++ "b/doc/13.5 - \345\212\240\345\205\245Swoole\345\274\200\345\217\221\347\273\204.md"
@@ -6,6 +6,6 @@
* 为`swoole`项目贡献`C/C++`代码,并被官方采纳
* 为`swoole`项目撰写文档,并被官方采纳
-* 为`swoole`项目贡献单元测试脚本
+* 为`swoole`项目贡献单元测试脚本.
加入`swoole`开发组后,我们会为你开通`@swoole.com`邮件组和`Github`账户权限。
\ No newline at end of file
diff --git "a/doc/13.5 - \351\231\204\345\275\225\357\274\232Linux\344\277\241\345\217\267\345\210\227\350\241\250.md" "b/doc/13.6 - \351\231\204\345\275\225\357\274\232Linux\344\277\241\345\217\267\345\210\227\350\241\250.md"
similarity index 100%
rename from "doc/13.5 - \351\231\204\345\275\225\357\274\232Linux\344\277\241\345\217\267\345\210\227\350\241\250.md"
rename to "doc/13.6 - \351\231\204\345\275\225\357\274\232Linux\344\277\241\345\217\267\345\210\227\350\241\250.md"
diff --git "a/doc/13.6 - \351\231\204\345\275\225\357\274\232Linux\351\224\231\350\257\257\344\277\241\346\201\257(errno)\345\210\227\350\241\250.md" "b/doc/13.7 - \351\231\204\345\275\225\357\274\232Linux\351\224\231\350\257\257\344\277\241\346\201\257(errno)\345\210\227\350\241\250.md"
similarity index 100%
rename from "doc/13.6 - \351\231\204\345\275\225\357\274\232Linux\351\224\231\350\257\257\344\277\241\346\201\257(errno)\345\210\227\350\241\250.md"
rename to "doc/13.7 - \351\231\204\345\275\225\357\274\232Linux\351\224\231\350\257\257\344\277\241\346\201\257(errno)\345\210\227\350\241\250.md"
diff --git "a/doc/13.7 - \351\231\204\345\275\225\357\274\232TCP\350\277\236\346\216\245\347\232\204\347\212\266\346\200\201.md" "b/doc/13.8 - \351\231\204\345\275\225\357\274\232TCP\350\277\236\346\216\245\347\232\204\347\212\266\346\200\201.md"
similarity index 100%
rename from "doc/13.7 - \351\231\204\345\275\225\357\274\232TCP\350\277\236\346\216\245\347\232\204\347\212\266\346\200\201.md"
rename to "doc/13.8 - \351\231\204\345\275\225\357\274\232TCP\350\277\236\346\216\245\347\232\204\347\212\266\346\200\201.md"
diff --git "a/doc/13.8 - \351\231\204\345\275\225\357\274\232tcpdump\346\212\223\345\214\205\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md" "b/doc/13.9 - \351\231\204\345\275\225\357\274\232tcpdump\346\212\223\345\214\205\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
similarity index 100%
rename from "doc/13.8 - \351\231\204\345\275\225\357\274\232tcpdump\346\212\223\345\214\205\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
rename to "doc/13.9 - \351\231\204\345\275\225\357\274\232tcpdump\346\212\223\345\214\205\345\267\245\345\205\267\347\232\204\344\275\277\347\224\250.md"
diff --git a/doc/2 - Server.md b/doc/2 - Server.md
index 3bdfb77..6c2d8c3 100644
--- a/doc/2 - Server.md
+++ b/doc/2 - Server.md
@@ -51,3 +51,4 @@ $serv->connections; //当前服务器的客户端连接,可使用foreach遍历
进程/线程结构图
-----
![Swoole进程/线程结构图](https://wiki.swoole.com/static/image/process.jpg)
+![进程/线程结构图2](https://wiki.swoole.com/static/uploads/wiki/201808/03/635680420659.png "进程/线程结构图2")
diff --git a/doc/2.1.1 - swoole_server::__construct.md b/doc/2.1.1 - swoole_server::__construct.md
index f8a9fa3..a275f4a 100644
--- a/doc/2.1.1 - swoole_server::__construct.md
+++ b/doc/2.1.1 - swoole_server::__construct.md
@@ -25,7 +25,7 @@ $serv = new swoole_server(string $host, int $port = 0, int $mode = SWOOLE_PROCES
* 构造函数中的参数与`swoole_server::addlistener`中是完全相同的
* 监听端口失败,在`1.9.16`以上版本会抛出异常,可以使用`try/catch`捕获异常,在`1.9.16`以下版本抛出致命错误
* __高负载的服务器,请务必调整[Linux内核参数](https://wiki.swoole.com/wiki/page/11)__
-* [ 3种Server运行模式介绍](https://wiki.swoole.com/wiki/page/353.html)
+* [ 2种Server运行模式介绍](https://wiki.swoole.com/wiki/page/353.html)
注意事项
----
diff --git a/doc/2.1.11 - swoole_server->tick.md b/doc/2.1.11 - swoole_server->tick.md
index a50b98c..efec7a7 100644
--- a/doc/2.1.11 - swoole_server->tick.md
+++ b/doc/2.1.11 - swoole_server->tick.md
@@ -17,8 +17,7 @@ function onReceive($server, $fd, $from_id, $data) {
```
在onWorkerStart中使用
--------------
-* 低于`1.8.0`版本task进程不能使用`tick/after`定时器,所以需要使用$serv->taskworker进行判断
-* task进程可以使用`addtimer`间隔定时器
+* 低于`1.8.0`版本task进程不能使用`tick/after`定时器,所以需要使用$serv->taskworker进行判断
```php
function onWorkerStart(swoole_server $serv, $worker_id)
@@ -30,7 +29,8 @@ function onWorkerStart(swoole_server $serv, $worker_id)
}
else
{
- $serv->addtimer(1000);
+ //task
+ $serv->tick(1000);
}
}
```
diff --git a/doc/2.1.14 - swoole_server->clearTimer.md b/doc/2.1.14 - swoole_server->clearTimer.md
index b32b131..e44461d 100644
--- a/doc/2.1.14 - swoole_server->clearTimer.md
+++ b/doc/2.1.14 - swoole_server->clearTimer.md
@@ -1,8 +1,11 @@
# swoole_server->clearTimer
-清除tick/after定时器,此函数是[swoole_timer_clear](https://wiki.swoole.com/wiki/page/387.html)的别名。
+清除`tick/after`定时器,此函数是 [swoole_timer_clear](https://wiki.swoole.com/wiki/page/387.html) 的别名。
-使用示例:
+> `clearTimer`仅可用于清除当前进程的定时器
+
+使用示例
+----
```php
$timer_id = $server->tick(1000, function ($id) use ($server) {
diff --git a/doc/2.1.24 - swoole_server->getClientInfo.md b/doc/2.1.24 - swoole_server->getClientInfo.md
index 764f3f8..a166c55 100644
--- a/doc/2.1.24 - swoole_server->getClientInfo.md
+++ b/doc/2.1.24 - swoole_server->getClientInfo.md
@@ -2,10 +2,17 @@
`swoole_server->getClientInfo`函数用来获取连接的信息,别名是`swoole_server->connection_info`
+函数原型
+---
```php
-function swoole_server->getClientInfo(int $fd, int $extraData, bool $ignoreError = false)
+bool|array swoole_server->getClientInfo(int $fd, int $extraData, bool $ignoreError = false)
```
+参数
+---
+
+返回值
+---
* 如果传入的`$fd`存在,将会返回一个数组
* 连接不存在或已关闭,返回`false`
* 第`3`个参数表示是否忽略错误,如果设置为`true`,即使连接关闭也会返回连接的信息
diff --git a/doc/2.1.29 - swoole_server->taskwait.md b/doc/2.1.29 - swoole_server->taskwait.md
index 3c93d67..59a3cfb 100644
--- a/doc/2.1.29 - swoole_server->taskwait.md
+++ b/doc/2.1.29 - swoole_server->taskwait.md
@@ -4,14 +4,25 @@
```php
function Server->taskwait(mixed $data, float $timeout = 0.5, int $dstWorkerId = -1) : string | bool
```
-`taskwait`与`task`方法作用相同,用于投递一个异步的任务到`task`进程池去执行。与`task`不同的是`taskwait`是阻塞等待的,直到任务完成或者超时返回。
+`taskwait`与`task`方法作用相同,用于投递一个异步的任务到`task`进程池去执行。与`task`不同的是`taskwait`是同步等待的,直到任务完成或者超时返回。
`$result`为任务执行的结果,由`$serv->finish`函数发出。如果此任务超时,这里会返回`false`。
-> `taskwait`是阻塞接口,如果你的Server是全异步的请使用`swoole_server::task`和`swoole_server::finish`,不要使用`taskwait`
-> 第3个参数可以指定要给投递给哪个task进程,传入ID即可,范围是`0 - serv->task_worker_num`
-> `$dstWorkerId`在`1.6.11`以上版本可用,可以指定目标Task进程的ID,默认为-1表示随机投递
+* 第`1`个参数为投递的任务数据,可以是任意类型,非字符串类型底层会自动进行串化
+* 第`2`个参数为超时时间,浮点型,单位为秒,最小支持`1ms`粒度,超过规定时间内`Task`进程未返回数据,`taskwait`将返回`false`,不再处理后续的任务结果数据
+* 第`3`个参数可以指定要给投递给哪个`Task`进程,传入`ID`即可,范围是`0 - serv->task_worker_num`
+* `$dstWorkerId`在`1.6.11`以上版本可用,可以指定目标`Task`进程的`ID`,默认为-1表示随机投递,底层会自动选择一个空闲`Task`进程
+
+
+> `4.0.4`以下版本中`taskwait`是阻塞接口,如果你的`Server`是全异步的请使用`swoole_server::task`和`swoole_server::finish`,不要使用`taskwait`
+> `4.0.4`以上版本中`taskwait`底层会进行协程调度,实现完全的异步`IO`
> `taskwait`方法不能在`task`进程中调用
+协程
+----
+从`4.0.4`版本开始`taskwait`方法将支持协程调度,在协程中调用`Server->taskwait()`时将自动进行协程调度,不再阻塞等待。
+
+借助协程调度器,`taskwait`可以实现并发调用。
+
特例
----
如果`onTask`中没有任何阻塞IO操作,底层仅有2次进程切换的开销,并不会产生IO等待,因此这种情况下 `taskwait` 可以视为非阻塞。实际测试`onTask`中仅读写PHP数组,进行10万次`taskwait`操作,总耗时仅为`1秒`,平均每次消耗为`10微秒`
\ No newline at end of file
diff --git a/doc/2.2.4 - swoole_server::$worker_id.md b/doc/2.2.4 - swoole_server::$worker_id.md
index 426f17f..2d52243 100644
--- a/doc/2.2.4 - swoole_server::$worker_id.md
+++ b/doc/2.2.4 - swoole_server::$worker_id.md
@@ -8,7 +8,7 @@ int $server->worker_id;
这个属性与`onWorkerStart`时的`$worker_id`是相同的。
-* `Worker`进程编号范围是`[0, $serv->setting['worker_num'])`
-* `Task`进程编号范围是`[$serv->setting['worker_num'], $serv->setting['worker_num'] + $serv->setting['task_worker_num'])`
+* `Worker`进程编号范围是`[0, $serv->setting['worker_num']]`
+* `Task`进程编号范围是`[$serv->setting['worker_num'], $serv->setting['worker_num'] + $serv->setting['task_worker_num']]`
> 工作进程重启后`worker_id`的值是不变的
\ No newline at end of file
diff --git a/doc/2.2.7 - swoole_server::$connections.md b/doc/2.2.7 - swoole_server::$connections.md
index 6dd4133..e1abd04 100644
--- a/doc/2.2.7 - swoole_server::$connections.md
+++ b/doc/2.2.7 - swoole_server::$connections.md
@@ -13,9 +13,13 @@ foreach($server->connections as $fd)
echo "当前服务器共有 ".count($server->connections). " 个连接\n";
```
-> 此属性在1.7.16以上版本可用
-> 连接迭代器依赖pcre库(不是PHP的pcre扩展),未安装pcre库无法使用此功能
-> pcre库的安装方法,
+> 此属性在`1.7.16`以上版本可用
+> 连接迭代器依赖`pcre`库(不是`PHP`的`pcre`扩展),未安装`pcre`库无法使用此功能
+> `pcre`库的安装方法,
+
+PCRE
+----
+安装好`PCRE`库后需要重新编译安装`swoole`,然后使用`php --ri swoole`查看`swoole`扩展相关信息中是否有`pcre => enabled`
Base 模式
----
diff --git a/doc/2.3.14 - log_file.md b/doc/2.3.14 - log_file.md
index ab8e50a..60f5e4f 100644
--- a/doc/2.3.14 - log_file.md
+++ b/doc/2.3.14 - log_file.md
@@ -19,9 +19,9 @@ log_file中的日志仅仅是做运行时错误记录,没有长久存储的必
重新打开日志文件
----
-在服务器程序运行期间日志文件被`mv`移动或`unlink`删除后,日志信息将无法正常写入,这时可以向Server发送`SIGRTMIN`信号实现重新打开日志文件。
+在服务器程序运行期间日志文件被`mv`移动或`unlink`删除后,日志信息将无法正常写入,这时可以向`Server`发送`SIGRTMIN`信号实现重新打开日志文件。
-* 在1.8.10或更高版本可用
+* 在`1.8.10`或更高版本可用
* 仅支持`Linux`平台
-
+* 不支持`UserProcess`进程
diff --git a/doc/2.3.18 - open_eof_check.md b/doc/2.3.18 - open_eof_check.md
index bd702c1..b15f3e2 100644
--- a/doc/2.3.18 - open_eof_check.md
+++ b/doc/2.3.18 - open_eof_check.md
@@ -1,16 +1,18 @@
# open_eof_check
-打开EOF检测,此选项将检测客户端连接发来的数据,当数据包结尾是指定的字符串时才会投递给Worker进程。否则会一直拼接数据包,直到超过缓存区或者超时才会中止。当出错时swoole底层会认为是恶意连接,丢弃数据并强制关闭连接。
+打开`EOF`检测,此选项将检测客户端连接发来的数据,当数据包结尾是指定的字符串时才会投递给`Worker`进程。否则会一直拼接数据包,直到超过缓存区或者超时才会中止。当出错时底层会认为是恶意连接,丢弃数据并强制关闭连接。
+
+> 此配置仅对`STREAM`类型的`Socket`有效,如`TCP`、`Unix Socket Stream`
```php
array(
-'open_eof_check' => true, //打开EOF检测
-'package_eof' => "\r\n", //设置EOF
+ 'open_eof_check' => true, //打开EOF检测
+ 'package_eof' => "\r\n", //设置EOF
)
```
-常见的Memcache/SMTP/POP等协议都是以\r\n结束的,就可以使用此配置。开启后可以保证Worker进程一次性总是收到一个或者多个完整的数据包。
+常见的`Memcache/SMTP/POP`等协议都是以`\r\n`结束的,就可以使用此配置。开启后可以保证Worker进程一次性总是收到一个或者多个完整的数据包。
-> EOF检测不会从数据中间查找eof字符串,所以Worker进程可能会同时收到多个数据包,需要在应用层代码中自行explode("\r\n", $data) 来拆分数据包
-> 1.7.15版本增加了open_eof_split,支持从数据中查找EOF,并切分数据
+> `EOF`检测不会从数据中间查找`eof`字符串,所以`Worker`进程可能会同时收到多个数据包,需要在应用层代码中自行`explode("\r\n", $data)` 来拆分数据包
+> `1.7.15`版本增加了`open_eof_split`配置项,支持从数据中查找`EOF`,并切分数据
diff --git a/doc/2.3.21 - open_length_check.md b/doc/2.3.21 - open_length_check.md
index a930968..51fd7ec 100644
--- a/doc/2.3.21 - open_length_check.md
+++ b/doc/2.3.21 - open_length_check.md
@@ -4,6 +4,8 @@
长度协议提供了`3`个选项来控制协议细节。
+> 此配置仅对`STREAM`类型的`Socket`有效,如`TCP`、`Unix Socket Stream`
+
package_length_type
----
diff --git a/doc/2.3.27 - open_tcp_nodelay.md b/doc/2.3.27 - open_tcp_nodelay.md
index f916738..20c41d8 100644
--- a/doc/2.3.27 - open_tcp_nodelay.md
+++ b/doc/2.3.27 - open_tcp_nodelay.md
@@ -1,3 +1,5 @@
# open_tcp_nodelay
启用open_tcp_nodelay,开启后TCP连接发送数据时会关闭Nagle合并算法,立即发往客户端连接。在某些场景下,如http服务器,可以提升响应速度。
+
+> 默认情况下,发送数据采用Nagle 算法。这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,使用TCP_NODELAY选项可以禁止Nagle 算法。
\ No newline at end of file
diff --git a/doc/2.3.47 - open_websocket_close_frame.md b/doc/2.3.47 - open_websocket_close_frame.md
new file mode 100644
index 0000000..689f0b2
--- /dev/null
+++ b/doc/2.3.47 - open_websocket_close_frame.md
@@ -0,0 +1,26 @@
+# open_websocket_close_frame
+
+启用websocket协议中关闭帧(opcode为0x08的帧)在onMessage回调中接收,默认为false。
+
+开启后,可在WebSocketServer中的``onMessage``回调中接收到客户端或服务端发送的关闭帧,开发者可自行对其进行处理。
+
+示例:
+```php
+$server = new swoole_websocket_server("0.0.0.0", 9501);
+
+$server->set(array("open_websocket_close_frame" => true));
+
+$server->on('open', function (swoole_websocket_server $server, $request) {});
+
+$server->on('message', function (swoole_websocket_server $server, $frame) {
+ if ($frame->opcode == 0x08) {
+ echo "Close frame received: Code {$frame->code} Reason {$frame->reason}\n";
+ } else {
+ echo "Message received: {$frame->data}\n";
+ }
+});
+
+$server->on('close', function ($ser, $fd) {});
+
+$server->start();
+```
\ No newline at end of file
diff --git a/doc/2.3.47 - reload_async.md b/doc/2.3.48 - reload_async.md
similarity index 100%
rename from doc/2.3.47 - reload_async.md
rename to doc/2.3.48 - reload_async.md
diff --git a/doc/2.3.48 - tcp_fastopen.md b/doc/2.3.49 - tcp_fastopen.md
similarity index 100%
rename from doc/2.3.48 - tcp_fastopen.md
rename to doc/2.3.49 - tcp_fastopen.md
diff --git a/doc/2.3.49 - request_slowlog_file.md b/doc/2.3.50 - request_slowlog_file.md
similarity index 100%
rename from doc/2.3.49 - request_slowlog_file.md
rename to doc/2.3.50 - request_slowlog_file.md
diff --git a/doc/2.3.50 - enable_coroutine.md b/doc/2.3.51 - enable_coroutine.md
similarity index 97%
rename from doc/2.3.50 - enable_coroutine.md
rename to doc/2.3.51 - enable_coroutine.md
index 5d1176f..5a12fb0 100644
--- a/doc/2.3.50 - enable_coroutine.md
+++ b/doc/2.3.51 - enable_coroutine.md
@@ -40,11 +40,11 @@ $http = new swoole_http_server("127.0.0.1", 9501);
$http->set([
//关闭内置协程
'enable_coroutine' => false,
-])
+]);
$http->on("request", function ($request, $response) {
if ($request->server['request_uri'] == '/coro') {
- go(function () {
+ go(function () use ($response) {
co::sleep(0.2);
$response->header("Content-Type", "text/plain");
$response->end("Hello World\n");
diff --git a/doc/2.3.51 - max_coroutine.md b/doc/2.3.52 - max_coroutine.md
similarity index 100%
rename from doc/2.3.51 - max_coroutine.md
rename to doc/2.3.52 - max_coroutine.md
diff --git "a/doc/2.6 - \344\272\213\344\273\266\345\233\236\350\260\203\345\207\275\346\225\260.md" "b/doc/2.6 - \344\272\213\344\273\266\345\233\236\350\260\203\345\207\275\346\225\260.md"
index 400e2bf..33b40a1 100644
--- "a/doc/2.6 - \344\272\213\344\273\266\345\233\236\350\260\203\345\207\275\346\225\260.md"
+++ "b/doc/2.6 - \344\272\213\344\273\266\345\233\236\350\260\203\345\207\275\346\225\260.md"
@@ -35,5 +35,16 @@ $serv->on('Receive', function() {
}
```
+协程模式
+----
+`Swoole2/4`版本支持了协程,使用协程后事件回调函数将会并发地执行。协程是一种用户态线程实现,没有额外的调度消耗,仅占用内存。使用协程模式,可以理解为“**每次事件回调函数都会创建一个新的线程去执行,事件回调函数执行完成后,线程退出**”。
+
+如果希望关闭协程,可设置:
+```php
+$server->set(["enable_coroutine" => false, ]);
+```
+
+
+
diff --git "a/doc/2.7.11 - \345\234\250worker\350\277\233\347\250\213\345\206\205\347\233\221\345\220\254\344\270\200\344\270\252Server\347\253\257\345\217\243.md" "b/doc/2.7.11 - \345\234\250worker\350\277\233\347\250\213\345\206\205\347\233\221\345\220\254\344\270\200\344\270\252Server\347\253\257\345\217\243.md"
index 57c023b..a2f01ea 100644
--- "a/doc/2.7.11 - \345\234\250worker\350\277\233\347\250\213\345\206\205\347\233\221\345\220\254\344\270\200\344\270\252Server\347\253\257\345\217\243.md"
+++ "b/doc/2.7.11 - \345\234\250worker\350\277\233\347\250\213\345\206\205\347\233\221\345\220\254\344\270\200\344\270\252Server\347\253\257\345\217\243.md"
@@ -1,5 +1,7 @@
# 在worker进程内监听一个Server端口
+> 注意, 此文档内容可能已过期, swoole最新版支持多协议监听
+
在一些场景下,需要监听额外的端口提供特殊协议处理。如在HttpServer中需要监听8081端口,提供管理Server的功能。在Swoole扩展内置的服务中不支持同时处理2种协议,即使是使用了addlistener添加了多个端口也不能接受2种协议的请求包。
这时候可以使用本地监听来解决此问题,原理是在某一个worker进程内,创建stream_socket_server,并加入到swoole_event中。
diff --git "a/doc/2.9.3 - \345\205\250\347\220\203Web\346\241\206\346\236\266\346\235\203\345\250\201\346\200\247\350\203\275\346\265\213\350\257\225 Techempower Web Framework Benchmarks.md" "b/doc/2.9.3 - \345\205\250\347\220\203Web\346\241\206\346\236\266\346\235\203\345\250\201\346\200\247\350\203\275\346\265\213\350\257\225 Techempower Web Framework Benchmarks.md"
new file mode 100644
index 0000000..27c0be7
--- /dev/null
+++ "b/doc/2.9.3 - \345\205\250\347\220\203Web\346\241\206\346\236\266\346\235\203\345\250\201\346\200\247\350\203\275\346\265\213\350\257\225 Techempower Web Framework Benchmarks.md"
@@ -0,0 +1,11 @@
+# 全球Web框架权威性能测试 Techempower Web Framework Benchmarks
+
+最新跑分测试结果地址: [techempower](https://www.techempower.com/benchmarks/#section=test&runid=9d5522a6-2917-467a-9d7a-8c0f6a8ed790)
+
+Swoole领跑**动态语言第一**
+
+数据库IO操作测试, 使用基本业务代码无特殊优化
+
+**性能超过所有静态语言框架(使用MySQL而不是Postgre)**
+
+![](https://ws1.sinaimg.cn/large/006DQdzWgy1fuo43czvqej31na1emtvi.jpg)
\ No newline at end of file
diff --git a/doc/4 - Coroutine.md b/doc/4 - Coroutine.md
index 50bb1dc..73831f1 100644
--- a/doc/4 - Coroutine.md
+++ b/doc/4 - Coroutine.md
@@ -69,21 +69,16 @@ $http->start();
2. 请勿在**2.2以下的版本**的以下场景中触发协程切换:
* 析构函数
* 魔术方法`__call()` `__get()` `__set()` 等
-3. gcc 4.4下如果在编译swoole的时候(即make阶段),出现gcc warning:
-`dereferencing pointer ‘v.327’ does break strict-aliasing rules`、
-`dereferencing type-punned pointer will break strict-aliasing rules`
-请手动编辑Makefile,将` CFLAGS = -Wall -pthread -g -O2`替换为`CFLAGS = -Wall -pthread -g -O2 -fno-strict-aliasing`,然后重新编译`make clean;make;make install`
-4. 与xdebug、xhprof、blackfire等zend扩展不兼容,例如不能使用xhprof对协程server进行性能分析采样。
-5. 原生的call_user_func和call_user_func_array中无法使用协程client,请使用\Swoole\Coroutine::call_user_func和\Swoole\Coroutine::call_user_func_array代替,在PHP7中如果无法保证在编译时反射调用的类是编译器已知的,请统一使用协程版反射调用
+3. 与xdebug、xhprof、blackfire等zend扩展不兼容,例如不能使用xhprof对协程server进行性能分析采样。
协程组件
---------
1. TCP/UDP Client:`Swoole\Coroutine\Client`
2. HTTP/WebSocket Client:`Swoole\Coroutine\HTTP\Client`
3. HTTP2 Client:`Swoole\Coroutine\HTTP2\Client`
-3. Redis Client:`Swoole\Coroutine\Redis`
-4. Mysql Client:`Swoole\Coroutine\MySQL`
-4. Postgresql Client:`Swoole\Coroutine\PostgreSQL`
+4. Redis Client:`Swoole\Coroutine\Redis`
+5. Mysql Client:`Swoole\Coroutine\MySQL`
+6. Postgresql Client:`Swoole\Coroutine\PostgreSQL`
* 在协程`Server`中需要使用协程版`Client`,可以实现全异步`Server`
* 其他程序中可以使用`go`关键词手工创建协程
diff --git a/doc/4.1 - Coroutine.md b/doc/4.1 - Coroutine.md
index acb703b..3c97d64 100644
--- a/doc/4.1 - Coroutine.md
+++ b/doc/4.1 - Coroutine.md
@@ -13,7 +13,7 @@ Swoole\Coroutine::set(array(
设置最大协程数,超过限制后底层将无法创建新的协程。
#### stack_size
-设置单个协程初始栈的内存尺寸,默认为`8192`
+设置单个协程初始栈的内存尺寸,默认为`2M`
短名称
----
diff --git a/doc/4.1.1 - Coroutine::getuid.md b/doc/4.1.1 - Coroutine::getuid.md
index 99e1d07..4023110 100644
--- a/doc/4.1.1 - Coroutine::getuid.md
+++ b/doc/4.1.1 - Coroutine::getuid.md
@@ -16,3 +16,43 @@ function \Swoole\Coroutine::getuid() : int
```php
echo Swoole\Coroutine::getuid();
```
+
+cid分配机制
+---
+> [相关issue](https://github.com/swoole/swoole-src/issues/1977)
+
+cid map 使用了 bit map, 它在分配时总是会寻找下一个可用的比特位
+
+我们可以通过以下代码来确认这个事实:
+```php
+co::set([
+ 'max_coroutine' => PHP_INT_MAX,
+ 'log_level' => SWOOLE_LOG_INFO,
+ 'trace_flags' => 0
+]);
+$map = [];
+while (true) {
+ if (empty($map)){
+ $cid = go(function () {co::sleep(5);});
+ }else{
+ $cid = go(function () { });
+ }
+ if (!isset($map[$cid])) {
+ $map[$cid] = $cid;
+ } else {
+ var_dump(end($map));
+ var_dump($cid);
+ exit;
+ }
+}
+```
+它将会打印:
+```php
+int(524288)
+int(2)
+```
+
+所以我们有 `MAX_CORO_NUM_LIMIT => 0x80000`
+则在同一时间同一进程的协程数也不能超过 `524288`
+
+虽然它的分配数量存在上限, 但这个数值非常大, 一个进程不可能同时存在这么多协程, 除非你有一台超大内存的机器, 但那时候你也不必再担心这个问题
\ No newline at end of file
diff --git a/doc/4.1.14 - Coroutine::stats.md b/doc/4.1.14 - Coroutine::stats.md
index 305d8cd..c603452 100644
--- a/doc/4.1.14 - Coroutine::stats.md
+++ b/doc/4.1.14 - Coroutine::stats.md
@@ -11,6 +11,9 @@ function \Swoole\Coroutine::stats() : array
----
* `coroutine_num`: 当前运行的协程数量
+* `coroutine_peak_num`: 当前运行的协程数量的峰值
+
+ 需要`4.0.5`或更高版本
```php
var_dump(Swoole\Coroutine::stats());
@@ -18,5 +21,7 @@ var_dump(Swoole\Coroutine::stats());
array(1) {
["coroutine_num"]=>
int(132)
+ ["coroutine_peak_num"]=>
+ int(2)
}
```
diff --git a/doc/4.1.15 - Coroutine::getBackTrace.md b/doc/4.1.15 - Coroutine::getBackTrace.md
new file mode 100644
index 0000000..17898b6
--- /dev/null
+++ b/doc/4.1.15 - Coroutine::getBackTrace.md
@@ -0,0 +1,50 @@
+# Coroutine::getBackTrace
+
+获取协程函数调用栈。
+
+```php
+function Coroutine::getBackTrace(int $cid=0, int $options=DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit=0) : array;
+```
+
+> 需要`4.1.0`或更高版本
+
+参数
+----
+* `$cid` 协程的`ID`,默认为当前协程
+* `$options` 设置选项
+ * `DEBUG_BACKTRACE_PROVIDE_OBJECT`: 是否填充`object`的索引
+ * `DEBUG_BACKTRACE_IGNORE_ARGS`: 是否忽略`args`的索引,包括所有的 `function/method` 的参数,能够节省内存开销
+* `$limit` 限制返回堆栈帧的数量
+
+返回值
+----
+* 指定的协程不存在,将返回`false`
+* 成功返回数组,格式与 [debug_backtrace](http://php.net/manual/zh/function.debug-backtrace.php) 函数返回值相同
+
+使用实例
+----
+```php
+function test1() {
+ test2();
+}
+
+function test2() {
+ while(true) {
+ co::sleep(10);
+ echo __FUNCTION__." \n";
+ }
+}
+
+$cid = go(function () {
+ test1();
+});
+
+go(function () use ($cid) {
+ while(true) {
+ echo "BackTrace[$cid]:\n-----------------------------------------------\n";
+ //返回数组,需要自行格式化输出
+ var_dump(co::getBackTrace($cid))."\n";
+ co::sleep(3);
+ }
+});
+```
\ No newline at end of file
diff --git a/doc/4.1.16 - Coroutine::listCoroutines.md b/doc/4.1.16 - Coroutine::listCoroutines.md
new file mode 100644
index 0000000..6087cfc
--- /dev/null
+++ b/doc/4.1.16 - Coroutine::listCoroutines.md
@@ -0,0 +1,19 @@
+# Coroutine::listCoroutines
+
+遍历当前进程内的所有协程。
+
+```php
+function Coroutine::listCoroutines() : Iterator
+```
+
+> 需要`4.1.0`或更高版本
+
+* 返回迭代器,可使用`foreach`遍历,或使用`iterator_to_array`转为数组
+
+```php
+$coros = Coroutine::listCoroutines();
+foreach($coros as $cid)
+{
+ var_dump(Coroutine::getBackTrace($cid));
+}
+```
\ No newline at end of file
diff --git a/doc/4.1.5 - Coroutine::fread.md b/doc/4.1.5 - Coroutine::fread.md
index 3f18587..c3a7107 100644
--- a/doc/4.1.5 - Coroutine::fread.md
+++ b/doc/4.1.5 - Coroutine::fread.md
@@ -18,6 +18,12 @@ function Coroutine::fread(resource $handle, int $length = 0);
----
读取成功返回字符串内容,读取失败返回`false`
+版本差异
+---
+`4.0.4`以下版本`fread`方法不支持非文件类型的`stream`,如`STDIN`、`Socket`,请勿使用`fread`操作此类资源。
+
+`4.0.4`以上版本`fread`方法支持了非文件类型的`stream`资源,底层会自动根据`stream`类型选择使用`AIO`线程池或`EventLoop`实现。
+
示例
---
```php
diff --git a/doc/4.1.6 - Coroutine::fgets.md b/doc/4.1.6 - Coroutine::fgets.md
index b0e46ac..7f5e6fb 100644
--- a/doc/4.1.6 - Coroutine::fgets.md
+++ b/doc/4.1.6 - Coroutine::fgets.md
@@ -6,7 +6,8 @@ function Coroutine::fgets(resource $handle);
```
`Co::fgets`底层使用了`php_stream`缓存区,默认大小为`8192`字节,可使用`stream_set_chunk_size`设置缓存区尺寸。
-> 需要`2.1.1`或更高版本
+> 需要`2.1.1`或更高版本
+> `fgets`函数仅可用于文件类型的`stream`资源
参数
----
diff --git a/doc/4.1.7 - Coroutine::fwrite.md b/doc/4.1.7 - Coroutine::fwrite.md
index 5dba461..b4b2141 100644
--- a/doc/4.1.7 - Coroutine::fwrite.md
+++ b/doc/4.1.7 - Coroutine::fwrite.md
@@ -19,6 +19,12 @@ function Coroutine::fwrite(resource $handle, string $data, int $length = 0);
----
写入成功返回数据长度,失败返回`false`
+版本差异
+---
+`4.0.4`以下版本`fwrite`方法不支持非文件类型的`stream`,如`STDOUT`、`Socket`,请勿使用`fwrite`操作此类资源。
+
+`4.0.4`以上版本`fwrite`方法支持了非文件类型的`stream`资源,底层会自动根据`stream`类型选择使用`AIO`线程池或`EventLoop`实现。
+
示例
---
```php
diff --git a/doc/4.10 - Runtime::enableCoroutine.md b/doc/4.10 - Runtime::enableCoroutine.md
new file mode 100644
index 0000000..185ad0a
--- /dev/null
+++ b/doc/4.10 - Runtime::enableCoroutine.md
@@ -0,0 +1,57 @@
+# Runtime::enableCoroutine
+
+在`4.1.0`版本中,底层增加一个新的特性,可以在运行时动态将基于`php_stream`实现的扩展、`PHP`网络客户端代码一键协程化。底层替换了`ZendVM` `Stream`的函数指针,所有使用`php_stream`进行`socket`操作均变成协程调度的异步`IO`。
+
+目前有`PHP`原生`Redis`、`PDO`、`MySQLi`协程化的支持。
+
+> `4.1`版本仅支持`tcp`和`unix`两种`stream`类型
+> `4.2`版本增加了对`udp`、`udg`、`unix`、`ssl`、`tls`类型的支持
+
+函数原型
+----
+```php
+function Runtime::enableCoroutine(bool $enable = true, int $flags = SWOOLE_HOOK_ALL);
+```
+
+* `$enable`:打开或关闭协程
+* `$flags`:选择要`Hook`的类型,可以多选,默认为全选。仅在`$enable = true`时有效
+
+> `$flags`参数在`4.2`或更高版本可用,请参考:[开关选项](https://wiki.swoole.com/wiki/page/993.html)
+
+可用列表
+----
+* `redis`扩展
+* 使用`mysqlnd`模式的`pdo`、`mysqli`扩展,如果未启用`mysqlnd`将不支持协程化
+* `soap`扩展
+* `file_get_contents`、`fopen`
+* `stream_socket_client`
+* `stream_socket_server`
+* `fsockopen`
+
+不可用列表
+----
+* `mysql`:底层使用`libmysqlclient`
+* `curl`:底层使用`libcurl` (即不能使用`CURL`驱动的`Guzzle`)
+* `mongo`:底层使用`mongo-c-client`
+* `pdo_pgsql`
+* `pdo_ori`
+* `pdo_odbc`
+* `pdo_firebird`
+
+使用实例
+----
+
+```php
+Swoole\Runtime::enableCoroutine();
+
+go(function () {
+ $redis = new redis;
+ $retval = $redis->connect("127.0.0.1", 6379);
+ var_dump($retval, $redis->getLastError());
+ var_dump($redis->get("key"));
+ var_dump($redis->set("key", "value2"));
+ var_dump($redis->get("key"));
+ $redis->close();
+});
+```
+
diff --git "a/doc/4.10.1 - \346\226\207\344\273\266\346\223\215\344\275\234.md" "b/doc/4.10.1 - \346\226\207\344\273\266\346\223\215\344\275\234.md"
new file mode 100644
index 0000000..5269087
--- /dev/null
+++ "b/doc/4.10.1 - \346\226\207\344\273\266\346\223\215\344\275\234.md"
@@ -0,0 +1,28 @@
+# 文件操作
+
+在`4.2.0`版本中增加了对文件操作的`Hook`,在运行时开启协程后。可以将文件读写的`IO`操作转为协程模式。
+
+底层使用了`AIO`线程池模拟实现,在`IO`完成时唤醒对应协程。
+
+可用列表
+----
+* `fopen`
+* `fread`/`fgets`
+* `fwrite`/`fputs`
+* `file_get_contents`、`file_put_contents`
+* `unlink`
+* `mkdir`
+* `rmdir`
+
+实例
+----
+```php
+Swoole\Runtime::enableCoroutine(true);
+
+go(function () {
+ $fp = fopen("test.log", "a+");
+ fwrite($fp, str_repeat('A', 2048);
+ fwrite($fp, str_repeat('B', 2048);
+ fclose();
+});
+```
diff --git "a/doc/4.10.2 - \347\235\241\347\234\240\345\207\275\346\225\260.md" "b/doc/4.10.2 - \347\235\241\347\234\240\345\207\275\346\225\260.md"
new file mode 100644
index 0000000..97fba77
--- /dev/null
+++ "b/doc/4.10.2 - \347\235\241\347\234\240\345\207\275\346\225\260.md"
@@ -0,0 +1,22 @@
+# 睡眠函数
+
+最新的`4.2.0`版本增加了对`sleep`函数的`Hook`,底层替换了`sleep`、`usleep`、`time_nanosleep`、`time_sleep_until`四个函数。
+
+当调用这些睡眠函数时会自动切换为协程定时器调度。不会阻塞进程。
+
+实例
+----
+```php
+Swoole\Runtime::enableCoroutine(true);
+
+go(function () {
+ sleep(1);
+ echo "sleep 1s\n';
+ usleep(1000);
+ echo "sleep 1ms\n"
+});
+```
+
+例外
+---
+由于底层的定时器最小粒度是`1ms`,因此使用`usleep`等高精度睡眠函数时,如果设置为低于`1ms`时,将直接使用`sleep`系统调用。可能会引起非常短暂的睡眠阻塞。
\ No newline at end of file
diff --git "a/doc/4.10.3 - \345\274\200\345\205\263\351\200\211\351\241\271.md" "b/doc/4.10.3 - \345\274\200\345\205\263\351\200\211\351\241\271.md"
new file mode 100644
index 0000000..c0faee2
--- /dev/null
+++ "b/doc/4.10.3 - \345\274\200\345\205\263\351\200\211\351\241\271.md"
@@ -0,0 +1,36 @@
+# 开关选项
+
+在`4.2`版本中,`Runtime::enableCoroutine`增加了第二个参数,可以设置开关选项,选择要`Hook`哪些`PHP`函数。
+
+支持的选项
+----
+* `SWOOLE_HOOK_SLEEP`:睡眠函数
+* `SWOOLE_HOOK_FILE`:文件操作`stream`
+* `SWOOLE_HOOK_TCP`:`TCP Socket`类型的`stream`
+* `SWOOLE_HOOK_UDP`:`UDP Socket`类型的`stream`
+* `SWOOLE_HOOK_UNIX`:`Unix Stream Socket`类型的`stream`
+* `SWOOLE_HOOK_UDG`:`Unix Dgram Socket`类型的`stream`
+* `SWOOLE_HOOK_SSL`:`SSL Socket`类型的`stream`
+* `SWOOLE_HOOK_TLS`:`TLS Socket`类型的`stream`
+* `SWOOLE_HOOK_ALL`:打开所有类型
+
+使用实例
+----
+```php
+Swoole\Runtime::enableCoroutine(true, SWOOLE_HOOK_SLEEP);
+
+go(function () {
+ sleep(1);
+ //注意仅 hook 了睡眠函数,下面的文件操作函数会导致阻塞
+ $fp = fopen("test.log", "a+");
+ fwrite($fp, str_repeat('A', 2048);
+ fwrite($fp, str_repeat('B', 2048);
+ fclose();
+});
+```
+
+关闭协程
+----
+调用`Runtime::enableCoroutine(false)`关闭上一次设置的所有选项协程`Hook`设置。
+
+注意关闭操作不接受第二个参数,底层会判断上一次打开时设置的选项列表,关闭对应的协程`Hook`设置。
diff --git a/doc/4.10 - Server.md b/doc/4.11 - Server.md
similarity index 100%
rename from doc/4.10 - Server.md
rename to doc/4.11 - Server.md
diff --git "a/doc/4.11 - \345\271\266\345\217\221\350\260\203\347\224\250.md" "b/doc/4.12 - \345\271\266\345\217\221\350\260\203\347\224\250.md"
similarity index 100%
rename from "doc/4.11 - \345\271\266\345\217\221\350\260\203\347\224\250.md"
rename to "doc/4.12 - \345\271\266\345\217\221\350\260\203\347\224\250.md"
diff --git "a/doc/4.11.1 - \344\275\277\347\224\250\345\256\236\344\276\213.md" "b/doc/4.12.1 - Defer \346\234\272\345\210\266.md"
similarity index 98%
rename from "doc/4.11.1 - \344\275\277\347\224\250\345\256\236\344\276\213.md"
rename to "doc/4.12.1 - Defer \346\234\272\345\210\266.md"
index c60d659..7126157 100644
--- "a/doc/4.11.1 - \344\275\277\347\224\250\345\256\236\344\276\213.md"
+++ "b/doc/4.12.1 - Defer \346\234\272\345\210\266.md"
@@ -1,4 +1,4 @@
-# 使用实例
+# Defer 机制
协程版本Client并发请求示例代码:
```php
diff --git "a/doc/4.11.2 - \345\255\220\345\215\217\347\250\213+\351\200\232\351\201\223.md" "b/doc/4.12.2 - \345\255\220\345\215\217\347\250\213+\351\200\232\351\201\223.md"
similarity index 100%
rename from "doc/4.11.2 - \345\255\220\345\215\217\347\250\213+\351\200\232\351\201\223.md"
rename to "doc/4.12.2 - \345\255\220\345\215\217\347\250\213+\351\200\232\351\201\223.md"
diff --git "a/doc/4.12 - \345\256\236\347\216\260\345\216\237\347\220\206.md" "b/doc/4.13 - \345\256\236\347\216\260\345\216\237\347\220\206.md"
similarity index 100%
rename from "doc/4.12 - \345\256\236\347\216\260\345\216\237\347\220\206.md"
rename to "doc/4.13 - \345\256\236\347\216\260\345\216\237\347\220\206.md"
diff --git "a/doc/4.12.1 - \345\215\217\347\250\213\344\270\216\347\272\277\347\250\213.md" "b/doc/4.13.1 - \345\215\217\347\250\213\344\270\216\347\272\277\347\250\213.md"
similarity index 100%
rename from "doc/4.12.1 - \345\215\217\347\250\213\344\270\216\347\272\277\347\250\213.md"
rename to "doc/4.13.1 - \345\215\217\347\250\213\344\270\216\347\272\277\347\250\213.md"
diff --git "a/doc/4.12.2 - \345\217\221\351\200\201\346\225\260\346\215\256\345\215\217\347\250\213\350\260\203\345\272\246.md" "b/doc/4.13.2 - \345\217\221\351\200\201\346\225\260\346\215\256\345\215\217\347\250\213\350\260\203\345\272\246.md"
similarity index 100%
rename from "doc/4.12.2 - \345\217\221\351\200\201\346\225\260\346\215\256\345\215\217\347\250\213\350\260\203\345\272\246.md"
rename to "doc/4.13.2 - \345\217\221\351\200\201\346\225\260\346\215\256\345\215\217\347\250\213\350\260\203\345\272\246.md"
diff --git "a/doc/4.12.3 - \345\215\217\347\250\213\345\206\205\345\255\230\345\274\200\351\224\200.md" "b/doc/4.13.3 - \345\215\217\347\250\213\345\206\205\345\255\230\345\274\200\351\224\200.md"
similarity index 90%
rename from "doc/4.12.3 - \345\215\217\347\250\213\345\206\205\345\255\230\345\274\200\351\224\200.md"
rename to "doc/4.13.3 - \345\215\217\347\250\213\345\206\205\345\255\230\345\274\200\351\224\200.md"
index b88c399..892500d 100644
--- "a/doc/4.12.3 - \345\215\217\347\250\213\345\206\205\345\255\230\345\274\200\351\224\200.md"
+++ "b/doc/4.13.3 - \345\215\217\347\250\213\345\206\205\345\255\230\345\274\200\351\224\200.md"
@@ -2,7 +2,9 @@
新版本`4.0`使用了`C`栈+`PHP`栈的协程实现方案。`Server`程序每次请求的事件回调函数中会创建一个新协程,处理完成后协程退出。
-在协程创建时需要创建一个全新的内存段作为`C`和`PHP`的栈,底层默认分配`2M(C)`虚拟内存+`8K(PHP)`内存。实际并不会分配这么内存,系统会根据在内存实际读写时发生缺页中断,再分配实际内存。
+在协程创建时需要创建一个全新的内存段作为`C`和`PHP`的栈,底层默认分配`2M(C)`虚拟内存+`8K(PHP)`内存(`PHP-7.2`或更高版本)。实际并不会分配这么内存,系统会根据在内存实际读写时发生缺页中断,再分配实际内存。
+
+> 由于`PHP-7.1/7.0`未提供设置栈内存尺寸的接口,这些版本每个协程将申请`256K`的`PHP`内存
相比于异步回调程序,协程会增加一些内存管理的开销。有一定性能损耗。经过压测`QPS`依然可以达到较高的水平。
diff --git "a/doc/4.12.4 - 4.0 \345\215\217\347\250\213\345\256\236\347\216\260\345\216\237\347\220\206.md" "b/doc/4.13.4 - 4.0 \345\215\217\347\250\213\345\256\236\347\216\260\345\216\237\347\220\206.md"
similarity index 86%
rename from "doc/4.12.4 - 4.0 \345\215\217\347\250\213\345\256\236\347\216\260\345\216\237\347\220\206.md"
rename to "doc/4.13.4 - 4.0 \345\215\217\347\250\213\345\256\236\347\216\260\345\216\237\347\220\206.md"
index 54b1527..8707367 100644
--- "a/doc/4.12.4 - 4.0 \345\215\217\347\250\213\345\256\236\347\216\260\345\216\237\347\220\206.md"
+++ "b/doc/4.13.4 - 4.0 \345\215\217\347\250\213\345\256\236\347\216\260\345\216\237\347\220\206.md"
@@ -49,30 +49,21 @@ static inline void sw_vm_stack_init(void)
int sw_coro_resume(php_context *sw_current_context, zval *retval, zval *coro_retval)
{
coro_task *task = SWCC(current_task);
- COROG.call_stack[COROG.call_stack_size++] = task;
- COROG.current_coro = task;
- swTraceLog(SW_TRACE_COROUTINE,"sw_coro_resume coro id %d", COROG.current_coro->cid);
- task->state = SW_CORO_RUNNING;
- EG(current_execute_data) = SWCC(current_execute_data);
- EG(vm_stack) = SWCC(current_vm_stack);
- EG(vm_stack_top) = SWCC(current_vm_stack_top);
- EG(vm_stack_end) = SWCC(current_vm_stack_end);
-
+ resume_php_stack(task);
if (EG(current_execute_data)->prev_execute_data->opline->result_type != IS_UNUSED && retval)
{
ZVAL_COPY(SWCC(current_coro_return_value_ptr), retval);
}
- // main OG
if (OG(handlers).elements)
{
- php_output_deactivate(); // free main
+ php_output_deactivate();
if (!SWCC(current_coro_output_ptr))
{
- php_output_activate(); // reset output
+ php_output_activate();
}
}
- // resume output control global
+
if (SWCC(current_coro_output_ptr))
{
memcpy(SWOG, SWCC(current_coro_output_ptr), sizeof(zend_output_globals));
@@ -80,8 +71,8 @@ int sw_coro_resume(php_context *sw_current_context, zval *retval, zval *coro_ret
SWCC(current_coro_output_ptr) = NULL;
}
- swDebug("cid=%d", task->cid);
- coroutine_resume(task->co);
+ swTraceLog(SW_TRACE_COROUTINE, "cid=%d", task->cid);
+ coroutine_resume_naked(task->co);
if (unlikely(EG(exception)))
{
@@ -93,6 +84,7 @@ int sw_coro_resume(php_context *sw_current_context, zval *retval, zval *coro_ret
}
return CORO_END;
}
+
```
协程调度
diff --git "a/doc/4.13 - \345\270\270\350\247\201\351\227\256\351\242\230.md" "b/doc/4.14 - \345\270\270\350\247\201\351\227\256\351\242\230.md"
similarity index 100%
rename from "doc/4.13 - \345\270\270\350\247\201\351\227\256\351\242\230.md"
rename to "doc/4.14 - \345\270\270\350\247\201\351\227\256\351\242\230.md"
diff --git "a/doc/4.13.1 - \350\277\220\350\241\214\344\270\255\345\207\272\347\216\260 Fatal error: Maximum function nesting level of '1000' reached, aborting!.md" "b/doc/4.14.1 - \350\277\220\350\241\214\344\270\255\345\207\272\347\216\260 Fatal error: Maximum function nesting level of '1000' reached, aborting!.md"
similarity index 100%
rename from "doc/4.13.1 - \350\277\220\350\241\214\344\270\255\345\207\272\347\216\260 Fatal error: Maximum function nesting level of '1000' reached, aborting!.md"
rename to "doc/4.14.1 - \350\277\220\350\241\214\344\270\255\345\207\272\347\216\260 Fatal error: Maximum function nesting level of '1000' reached, aborting!.md"
diff --git "a/doc/4.13.2 - \344\270\272\344\273\200\344\271\210\345\217\252\350\203\275\345\234\250\345\233\236\350\260\203\345\207\275\346\225\260\344\270\255\344\275\277\347\224\250\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md" "b/doc/4.14.2 - \344\270\272\344\273\200\344\271\210\345\217\252\350\203\275\345\234\250\345\233\236\350\260\203\345\207\275\346\225\260\344\270\255\344\275\277\347\224\250\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md"
similarity index 100%
rename from "doc/4.13.2 - \344\270\272\344\273\200\344\271\210\345\217\252\350\203\275\345\234\250\345\233\236\350\260\203\345\207\275\346\225\260\344\270\255\344\275\277\347\224\250\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md"
rename to "doc/4.14.2 - \344\270\272\344\273\200\344\271\210\345\217\252\350\203\275\345\234\250\345\233\236\350\260\203\345\207\275\346\225\260\344\270\255\344\275\277\347\224\250\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md"
diff --git "a/doc/4.13.3 - \346\224\257\346\214\201\345\215\217\347\250\213\347\232\204\345\233\236\350\260\203\346\226\271\346\263\225\345\210\227\350\241\250.md" "b/doc/4.14.3 - \346\224\257\346\214\201\345\215\217\347\250\213\347\232\204\345\233\236\350\260\203\346\226\271\346\263\225\345\210\227\350\241\250.md"
similarity index 100%
rename from "doc/4.13.3 - \346\224\257\346\214\201\345\215\217\347\250\213\347\232\204\345\233\236\350\260\203\346\226\271\346\263\225\345\210\227\350\241\250.md"
rename to "doc/4.14.3 - \346\224\257\346\214\201\345\215\217\347\250\213\347\232\204\345\233\236\350\260\203\346\226\271\346\263\225\345\210\227\350\241\250.md"
diff --git "a/doc/4.14.4 - \351\224\231\350\257\257\344\277\241\346\201\257\357\274\232 XXXX client has already been bound to another coroutine.md" "b/doc/4.14.4 - \351\224\231\350\257\257\344\277\241\346\201\257\357\274\232 XXXX client has already been bound to another coroutine.md"
new file mode 100644
index 0000000..3dfc4ba
--- /dev/null
+++ "b/doc/4.14.4 - \351\224\231\350\257\257\344\277\241\346\201\257\357\274\232 XXXX client has already been bound to another coroutine.md"
@@ -0,0 +1,29 @@
+# 错误信息: XXXX client has already been bound to another coroutine
+
+使用协程客户端时出现以下错误信息:
+```shell
+redis client has already been bound to another coroutine.
+```
+
+这表示在两个协程内使用了同一个客户端。请修改`PHP`代码,避免出现此情况。
+
+错误实例
+----
+```php
+$redis = new Co\Redis;
+
+go(function () use ($redis) {
+ $redis->get("key");
+});
+
+go(function () use ($redis) {
+ $redis->get("key");
+});
+```
+
+例子中两个协程同时使用`$redis->get`进行`IO`操作,会引起混乱。底层在第二个协程调用`$redis->get`时会抛出上述致命错误。
+
+解决方案
+----
+使用`Swoole\Coroutine\Channel`或`SplQueue`实现连接池,管理协程客户端资源。一个客户端对象仅用于一个协程,操作完毕后,再释放给其他协程使用。
+
diff --git "a/doc/4.14.5 - Swoole4 \345\215\217\347\250\213\344\270\216 PHP \347\232\204 Yield\357\274\217Generator \345\215\217\347\250\213\346\234\211\344\273\200\344\271\210\345\214\272\345\210\253.md" "b/doc/4.14.5 - Swoole4 \345\215\217\347\250\213\344\270\216 PHP \347\232\204 Yield\357\274\217Generator \345\215\217\347\250\213\346\234\211\344\273\200\344\271\210\345\214\272\345\210\253.md"
new file mode 100644
index 0000000..fd10840
--- /dev/null
+++ "b/doc/4.14.5 - Swoole4 \345\215\217\347\250\213\344\270\216 PHP \347\232\204 Yield\357\274\217Generator \345\215\217\347\250\213\346\234\211\344\273\200\344\271\210\345\214\272\345\210\253.md"
@@ -0,0 +1,7 @@
+# Swoole4 协程与 PHP 的 Yield/Generator 协程有什么区别
+
+在一些框架中使用了`PHP`的`Yield/Generator`来实现半自动化的协程。实际使用中,开发者需要在涉及协程逻辑的函数调用前增加`yield`关键字。这带来了额外的学习成本和编程心智负担,非常容易犯错。`Yield/Generator`代码风格与传统的同步风格代码存在冲突。无法复用已有代码。
+
+`Swoole4`协程是全自动化的协程,开发者无需添加任何关键字,底层自动实现协程的切换和调度。`Swoole4`协程风格与传统的同步风格代码是一致的,因此可以复用已有代码。
+
+在`4.1.0`版本中,底层增加了`php_stream`兼容层,可一键地将`redis`、`mysqli`、`pdo`和其他`tcp socket stream`代码协程化。
\ No newline at end of file
diff --git "a/doc/4.14 - \347\274\226\347\250\213\351\241\273\347\237\245.md" "b/doc/4.15 - \347\274\226\347\250\213\351\241\273\347\237\245.md"
similarity index 100%
rename from "doc/4.14 - \347\274\226\347\250\213\351\241\273\347\237\245.md"
rename to "doc/4.15 - \347\274\226\347\250\213\351\241\273\347\237\245.md"
diff --git "a/doc/4.14.1 - \345\234\250\345\244\232\344\270\252\345\215\217\347\250\213\351\227\264\345\205\261\347\224\250\345\220\214\344\270\200\344\270\252\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md" "b/doc/4.15.1 - \345\234\250\345\244\232\344\270\252\345\215\217\347\250\213\351\227\264\345\205\261\347\224\250\345\220\214\344\270\200\344\270\252\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md"
similarity index 100%
rename from "doc/4.14.1 - \345\234\250\345\244\232\344\270\252\345\215\217\347\250\213\351\227\264\345\205\261\347\224\250\345\220\214\344\270\200\344\270\252\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md"
rename to "doc/4.15.1 - \345\234\250\345\244\232\344\270\252\345\215\217\347\250\213\351\227\264\345\205\261\347\224\250\345\220\214\344\270\200\344\270\252\345\215\217\347\250\213\345\256\242\346\210\267\347\253\257.md"
diff --git "a/doc/4.14.2 - \347\246\201\346\255\242\344\275\277\347\224\250\345\215\217\347\250\213 API \347\232\204\345\234\272\346\231\257 (Swoole4\344\273\245\344\270\213\347\211\210\346\234\254).md" "b/doc/4.15.2 - \347\246\201\346\255\242\344\275\277\347\224\250\345\215\217\347\250\213 API \347\232\204\345\234\272\346\231\257 (Swoole4\344\273\245\344\270\213\347\211\210\346\234\254).md"
similarity index 100%
rename from "doc/4.14.2 - \347\246\201\346\255\242\344\275\277\347\224\250\345\215\217\347\250\213 API \347\232\204\345\234\272\346\231\257 (Swoole4\344\273\245\344\270\213\347\211\210\346\234\254).md"
rename to "doc/4.15.2 - \347\246\201\346\255\242\344\275\277\347\224\250\345\215\217\347\250\213 API \347\232\204\345\234\272\346\231\257 (Swoole4\344\273\245\344\270\213\347\211\210\346\234\254).md"
diff --git "a/doc/4.14.3 - \344\275\277\347\224\250\347\261\273\351\235\231\346\200\201\345\217\230\351\207\217\357\274\217\345\205\250\345\261\200\345\217\230\351\207\217\344\277\235\345\255\230\344\270\212\344\270\213\346\226\207.md" "b/doc/4.15.3 - \344\275\277\347\224\250\347\261\273\351\235\231\346\200\201\345\217\230\351\207\217\357\274\217\345\205\250\345\261\200\345\217\230\351\207\217\344\277\235\345\255\230\344\270\212\344\270\213\346\226\207.md"
similarity index 100%
rename from "doc/4.14.3 - \344\275\277\347\224\250\347\261\273\351\235\231\346\200\201\345\217\230\351\207\217\357\274\217\345\205\250\345\261\200\345\217\230\351\207\217\344\277\235\345\255\230\344\270\212\344\270\213\346\226\207.md"
rename to "doc/4.15.3 - \344\275\277\347\224\250\347\261\273\351\235\231\346\200\201\345\217\230\351\207\217\357\274\217\345\205\250\345\261\200\345\217\230\351\207\217\344\277\235\345\255\230\344\270\212\344\270\213\346\226\207.md"
diff --git "a/doc/4.16 - \351\200\200\345\207\272\345\215\217\347\250\213.md" "b/doc/4.16 - \351\200\200\345\207\272\345\215\217\347\250\213.md"
new file mode 100644
index 0000000..c5f48e5
--- /dev/null
+++ "b/doc/4.16 - \351\200\200\345\207\272\345\215\217\347\250\213.md"
@@ -0,0 +1,97 @@
+# 退出协程
+
+> 在Swoole低版本中, 协程中使用exit强行退出脚本会导致内存错误导致不可预期的结果或coredump, 在Swoole服务中使用exit会使整个服务进程退出且内部的协程全部异常终止导致严重问题
+
+> Swoole长期以来一直禁止开发者使用exit, 但开发者可以使用抛出异常这种非常规的方式, 在顶层catch来实现和exit相同的退出逻辑
+
+> 4.2.2版本及以上允许脚本(未创建http_server)在只有当前协程的情况下exit退出
+
+Swoole**`4.1.0`**版本及以上直接支持了在`协程`, `服务事件循环`中使用PHP的`exit`, 此时底层会自动抛出一个可捕获的`Swoole\\ExitException`, 开发者可以在需要的位置捕获并实现与原生PHP一样的退出逻辑.
+
+---
+
+`Swoole\\ExitException`继承于`Exception`且新增了两个方法`getStatus`和`getFlags`:
+
+类原型:
+---
+```php
+namespace Swoole;
+class ExitException extends \Exception
+{
+ public function getStatus():mixed
+ public function getFlags():int
+}
+```
+
+函数原型
+---
+```php
+public function getStatus():mixed
+```
+获取exit($status)退出时的传入的`status`参数, 支持任意的变量类型
+
+```php
+public function getFlags():int
+```
+获取exit退出时所处的环境信息掩码, 目前有以下掩码
+```C
+SWOOLE_EXIT_IN_COROUTINE //协程中退出
+SWOOLE_EXIT_IN_SERVER //服务中退出
+```
+使用方法
+---
+#### 基本使用
+```php
+function route()
+{
+ controller();
+}
+
+function controller()
+{
+ your_code();
+}
+
+function your_code()
+{
+ co::sleep(.001);
+ exit(1);
+}
+
+go(function () {
+ try {
+ route();
+ } catch (\Swoole\ExitException $e) {
+ assert($e->getStatus() === 1);
+ assert($e->getFlags() === SWOOLE_EXIT_IN_COROUTINE);
+ return;
+ }
+});
+```
+
+#### 带状态码的退出
+```php
+getStatus();
+ }
+});
+swoole_event_wait();
+exit($exit_status);
+```
+
+#### 关闭内置协程, 允许在异步中退出
+
+```php
+swoole_async_set([
+ 'enable_coroutine' => false
+]);
+swoole_timer_after(1000, function () {
+ exit;
+});
+```
\ No newline at end of file
diff --git "a/doc/4.17 - \346\211\251\345\261\225\347\273\204\344\273\266.md" "b/doc/4.17 - \346\211\251\345\261\225\347\273\204\344\273\266.md"
new file mode 100644
index 0000000..444d59a
--- /dev/null
+++ "b/doc/4.17 - \346\211\251\345\261\225\347\273\204\344\273\266.md"
@@ -0,0 +1,16 @@
+# 扩展组件
+
+从`4.1.2`版本开始底层提供了`Socket Hook`机制,可将`MongoDB`、`ZooKeeper`等`PHP`扩展编译为`Swoole4`协程版本。
+
+实现原理
+----
+底层提供了`socket_hook.h`和`file_hook.h`,在扩展源代码中找到`#include `的代码,下面插入`#include "ext/swoole/include/socket_hook.h"`即可。底层会自动替换`socket`相关的系统调用,转化为协程的`C`函数。
+
+如`recv()`系统调用将被转换为`swoole_coroutine_recv`,这个`C`函数实现是在`swoole.so`中。因此使用`socket_hook`的扩展,需要依赖`swoole`扩展,必须在`extension=swoole.so`之后加入。
+
+不仅是`PHP`扩展,其他的`C/C++`代码也可以使用这种方式实现协程化。
+
+兼容性
+----
+使用`socket_hook`协程化后的扩展,在非协程中依然是同步阻塞的。只有在`Swoole4`协程中才会被切换为协程模式。与同步模式可以保持兼容。
+
diff --git a/doc/4.17.1 - MongoDB.md b/doc/4.17.1 - MongoDB.md
new file mode 100644
index 0000000..d874a81
--- /dev/null
+++ b/doc/4.17.1 - MongoDB.md
@@ -0,0 +1,19 @@
+# MongoDB
+
+安装
+----
+下载`mongodb`扩展源码,修改`mongodb-1.5.2/src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c`文件,在其他头文件引入完毕后加入`#include "swoole/include/socket_hook.h"`。
+
+```shell
+pecl download mongodb
+cd mongodb-1.5.2/
+vim src/libmongoc/src/libmongoc/src/mongoc/mongoc-socket.c
+phpize
+make -j
+sudo make install
+```
+
+修改 php.ini
+---
+在`extension=swoole.so`下方加入`extension=mongodb.so`
+
diff --git "a/doc/4.2 - Coroutine\357\274\217Channel.md" "b/doc/4.2 - Coroutine\357\274\217Channel.md"
index 26a1320..d01162c 100644
--- "a/doc/4.2 - Coroutine\357\274\217Channel.md"
+++ "b/doc/4.2 - Coroutine\357\274\217Channel.md"
@@ -35,3 +35,48 @@ co::create(function () use ($chan) {
swoole_event::wait();
```
+连接池
+----
+使用`Chan`可以方便第实现连接池功能。管理各类`Socket`连接资源。
+
+```php
+class RedisPool
+{
+ /**
+ * @var \Swoole\Coroutine\Channel
+ */
+ protected $pool;
+
+ /**
+ * RedisPool constructor.
+ * @param int $size 连接池的尺寸
+ */
+ function __construct($size = 100)
+ {
+ $this->pool = new Swoole\Coroutine\Channel($size);
+ for ($i = 0; $i < $size; $i++)
+ {
+ $redis = new Swoole\Coroutine\Redis();
+ $res = $redis->connect('127.0.0.1', 6379);
+ if ($res == false)
+ {
+ throw new RuntimeException("failed to connect redis server.");
+ }
+ else
+ {
+ $this->put($redis);
+ }
+ }
+ }
+
+ function put($redis)
+ {
+ $this->pool->push($redis);
+ }
+
+ function get()
+ {
+ return $this->pool->pop();
+ }
+}
+```
diff --git "a/doc/4.2.1 - Coroutine\357\274\217Channel->__construct.md" "b/doc/4.2.1 - Coroutine\357\274\217Channel->__construct.md"
index 0d138fa..d4ff25d 100644
--- "a/doc/4.2.1 - Coroutine\357\274\217Channel->__construct.md"
+++ "b/doc/4.2.1 - Coroutine\357\274\217Channel->__construct.md"
@@ -3,21 +3,12 @@
通道构造方法。
```php
-Coroutine\Channel->__construct(int $capacity = 0)
+Coroutine\Channel->__construct(int $capacity = 1)
```
-* `$capacity`,设置容量,默认为`0`
+* `$capacity`,设置容量,默认为`1`,必须为大于或等于`1`的整数
* 底层使用`PHP`引用计数来保存变量,缓存区只需要占用 `$capacity * sizeof(zval)` 字节的内存
+* 在`Server`中使用时必须在`onWorkerStart`之后创建
-> `PHP7`版本下`zval`为`16`字节,如`$capacity = 1024`时,`Channel`将占用`16K`内存
-
-无缓冲区
----
-当设置为`0`时,底层将不再设置缓冲区,`push`和`pop`操作会立即挂起当前协程。
-
-有缓冲区
----
-* 当设置大于`0`的值时,将启用缓冲区。允许队列中缓存`$capacity`数量的`PHP`变量。
-* 即使没有任何消费者进行`pop`,然后可以向通道中写入`$capacity`次数据。
-* `push`写入的数据数量超过`$capacity`时,协程将会被挂起
+> `PHP7`版本下`zval`为`16`字节,如`$capacity = 1024`时,`Channel`最大将占用`16K`内存
diff --git "a/doc/4.2.11 - Coroutine\357\274\217Channel->$errCode.md" "b/doc/4.2.10 - Coroutine\357\274\217Channel->$errCode.md"
similarity index 100%
rename from "doc/4.2.11 - Coroutine\357\274\217Channel->$errCode.md"
rename to "doc/4.2.10 - Coroutine\357\274\217Channel->$errCode.md"
diff --git "a/doc/4.2.7 - Coroutine\357\274\217Channel->length.md" "b/doc/4.2.6 - Coroutine\357\274\217Channel->length.md"
similarity index 100%
rename from "doc/4.2.7 - Coroutine\357\274\217Channel->length.md"
rename to "doc/4.2.6 - Coroutine\357\274\217Channel->length.md"
diff --git "a/doc/4.2.8 - Coroutine\357\274\217Channel->isEmpty.md" "b/doc/4.2.7 - Coroutine\357\274\217Channel->isEmpty.md"
similarity index 100%
rename from "doc/4.2.8 - Coroutine\357\274\217Channel->isEmpty.md"
rename to "doc/4.2.7 - Coroutine\357\274\217Channel->isEmpty.md"
diff --git "a/doc/4.2.9 - Coroutine\357\274\217Channel->isFull.md" "b/doc/4.2.8 - Coroutine\357\274\217Channel->isFull.md"
similarity index 100%
rename from "doc/4.2.9 - Coroutine\357\274\217Channel->isFull.md"
rename to "doc/4.2.8 - Coroutine\357\274\217Channel->isFull.md"
diff --git "a/doc/4.2.10 - Coroutine\357\274\217Channel->$capacity.md" "b/doc/4.2.9 - Coroutine\357\274\217Channel->$capacity.md"
similarity index 100%
rename from "doc/4.2.10 - Coroutine\357\274\217Channel->$capacity.md"
rename to "doc/4.2.9 - Coroutine\357\274\217Channel->$capacity.md"
diff --git "a/doc/4.3 - Coroutine\357\274\217Client.md" "b/doc/4.3 - Coroutine\357\274\217Client.md"
index 43bc990..4d70461 100644
--- "a/doc/4.3 - Coroutine\357\274\217Client.md"
+++ "b/doc/4.3 - Coroutine\357\274\217Client.md"
@@ -20,3 +20,18 @@ $client->send("hello world\n");
echo $client->recv();
$client->close();
```
+
+协议处理
+----
+协程客户端也支持长度和`EOF`协议处理,设置方法与 [Swoole\Client](https://wiki.swoole.com/wiki/page/p-client_setting.html) 完全一致。
+
+```php
+$client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
+$client->set(array(
+ 'open_length_check' => 1,
+ 'package_length_type' => 'N',
+ 'package_length_offset' => 0, //第N个字节是包长度的值
+ 'package_body_offset' => 4, //第几个字节开始计算长度
+ 'package_max_length' => 2000000, //协议最大长度
+));
+```
\ No newline at end of file
diff --git "a/doc/4.3.1 - Coroutine\357\274\217Client->connect.md" "b/doc/4.3.1 - Coroutine\357\274\217Client->connect.md"
index 5248fa9..842846d 100644
--- "a/doc/4.3.1 - Coroutine\357\274\217Client->connect.md"
+++ "b/doc/4.3.1 - Coroutine\357\274\217Client->connect.md"
@@ -13,8 +13,9 @@ connect方法接受4个参数:
> 原先异步客户端不支持`recv`超时,现在协程版已经支持超时,复用上面的`$timeout`参数
+使用实例
-----
-connect不会发生阻塞,connect事件触发后,切回PHP上下文。
+`connect`不会发生阻塞,`connect`事件触发后,切回`PHP`上下文。
```php
if ($cli->connect('127.0.0.1', 9501)) {
@@ -23,5 +24,19 @@ if ($cli->connect('127.0.0.1', 9501)) {
echo "connect failed.";
}
```
-如果连接失败,会返回false
-> 超时后返回,检查$cli->errCode为110
\ No newline at end of file
+如果连接失败,会返回`false`
+> 超时后返回,检查`$cli->errCode`为`110`
+
+失败重试
+----
+`connect`连接失败后,不可直接进行重连。必须使用`close`关闭已有`socket`,然后再进行`connect`重试。
+
+```php
+//连接失败
+if ($cli->connect('127.0.0.1', 9501) == false) {
+ //关闭已有socket
+ $cli->close();
+ //重试
+ $cli->connect('127.0.0.1', 9501);
+}
+```
\ No newline at end of file
diff --git "a/doc/4.3.2 - Coroutine\357\274\217Client->send.md" "b/doc/4.3.2 - Coroutine\357\274\217Client->send.md"
index 0cc34cc..7e80e1a 100644
--- "a/doc/4.3.2 - Coroutine\357\274\217Client->send.md"
+++ "b/doc/4.3.2 - Coroutine\357\274\217Client->send.md"
@@ -2,10 +2,16 @@
发送数据,函数原型为
```php
-$client->send(string $data);
+function client->send(string $data);
```
-* $data为发送的数据,必须为字符串类型,支持二进制数据
-* 成功返回true,失败返回false
-* send操作是立即返回的,没有协程切换
+* `$data`为发送的数据,必须为字符串类型,支持二进制数据
+* 发生的数据过大可能会引起协程调度,监听可写后进行发送
+发送成功
+----
+发送成功返回写入`Socket`缓存区的字节数,底层会尽可能地将所有数据发出。如果返回的字节数与传入的`$data`长度不同,可能是`Socket`已被对端关闭,再下一次调用`send`或`recv`时将返回对应的错误码
+
+发送失败
+---
+返回`false`,请检查`$client->errCode`获取错误原因。
diff --git "a/doc/4.3.3 - Coroutine\357\274\217Client->recv.md" "b/doc/4.3.3 - Coroutine\357\274\217Client->recv.md"
index 9536481..7cb5395 100644
--- "a/doc/4.3.3 - Coroutine\357\274\217Client->recv.md"
+++ "b/doc/4.3.3 - Coroutine\357\274\217Client->recv.md"
@@ -17,3 +17,4 @@ function Coroutine\Client->recv(float $timeout = -1) : string;
* 传入了`$timeout`,优先使用制定的`timeout`参数
* 未传入`$timeout`,但在`connect`时指定了超时时间,自动以`connect`超时时间作为`recv`超时时间
* 未传入`$timeout`,未设置`connect`超时,将设置为`-1`表示永不超时
+* 发生超时的错误码为`ETIMEDOUT`
diff --git "a/doc/4.4 - Coroutine\357\274\217Http\357\274\217Client.md" "b/doc/4.4 - Coroutine\357\274\217Http\357\274\217Client.md"
index 5d302d9..39f978b 100644
--- "a/doc/4.4 - Coroutine\357\274\217Http\357\274\217Client.md"
+++ "b/doc/4.4 - Coroutine\357\274\217Http\357\274\217Client.md"
@@ -1,16 +1,38 @@
# Coroutine\Http\Client
- `Swoole-2.0.0`版本增加了对协程版`Http`客户端的支持。底层是用纯`C`编写,拥有超高的性能。
-
> 协程版Http客户端基于原生的AsyncIo中的异步Http客户端,基本的设置和使用方法和异步Http客户端一致,不在需要注册回调函数,只需要同步写法即可,使用方法和Swoole\Http\Client一致的此处不再列出,请参考 [swoole\AsyncIO\异步Http/WebSocket客户端](https://wiki.swoole.com/wiki/page/p-http_client.html),对于使用有区别的函数,此处单独说明
+`Swoole-2.0.0`版本增加了对协程版`Http`客户端的支持。底层是用纯`C`编写,拥有超高的性能。
+
+Saber - 人性化的协程HTTP客户端封装库
+---
+开发者可使用已封装的[协程HTTP客户端Saber](https://github.com/swlib/saber)
+
+* 基于Swoole协程Client开发
+* 人性化使用风格, ajax.js/axios.js/requests.py用户福音, 同时支持PSR风格操作
+* 浏览器级别完备的Cookie管理机制, 完美适配爬虫/API代理应用
+* 请求/响应/异常拦截器
+* 多请求并发, 并发重定向优化
+* 连接池, 自动化复用长连接
+* 通道池(Chan): 最大连接数限制+无阻塞
+* HTTPS连接, CA证书自动化支持
+* HTTP/Socks5 Proxy支持
+* WebSocket连接支持
+* 毫秒级超时定时器
+* 自动化 编码请求/解析响应 数据
+* 响应报文自动编码转换
+* 异步超大文件上传/下载, 断点重传
+* 自动重试机制
+* 单次并发数控制
+* 多模式/超细粒度异常处理机制
+
启用协程Http客户端
----
-* 需要在编译swoole时增加`--enable-coroutine`来开启此功能。
-* swoole_http_client不依赖任何第三方库
-* 支持`Http-Chunk`、`Keep-Alive`特性,已支持`form-data`格式
+* 不依赖任何第三方扩展库, 默认开启
+* 支持`Http-Chunk`、`Keep-Alive`特性,支持`form-data`格式
* Http协议版本为`HTTP/1.1`
-* `gzip`压缩格式支持需要依赖`zlib`库
+* 支持升级为websocket客户端
+* `gzip`压缩格式支持需要依赖`zlib`库(默认都有)
构造方法
---
diff --git "a/doc/4.4.5 - Coroutine\357\274\217Http\357\274\217Client->push.md" "b/doc/4.4.5 - Coroutine\357\274\217Http\357\274\217Client->push.md"
index 2b1793f..b85aac5 100644
--- "a/doc/4.4.5 - Coroutine\357\274\217Http\357\274\217Client->push.md"
+++ "b/doc/4.4.5 - Coroutine\357\274\217Http\357\274\217Client->push.md"
@@ -2,19 +2,25 @@
向`WebSocket`服务器推送消息。
```php
-function Coroutine\Http\Client->push(string $data, int $opcode = WEBSOCKET_OPCODE_TEXT,
+function Coroutine\Http\Client->push(mixed $data, int $opcode = WEBSOCKET_OPCODE_TEXT,
bool $finish = true): bool
```
* `push`方法必须在`upgrade`成功之后才能执行
* `push`方法不会产生协程调度,写入发送缓存区后会立即返回
-参数
+参数模式1
----
* `$data` 要发送的数据内容,默认为`UTF-8`文本格式,如果为其他格式编码或二进制数据,请使用`WEBSOCKET_OPCODE_BINARY`
* `$opcode`操作类型,默认为`WEBSOCKET_OPCODE_TEXT`表示发送文本
* `$opcode`必须为合法的`WebSocket OPCODE`,否则会返回失败,并打印错误信息`opcode max 10`
+参数模式2
+----
+> 需要4.2.0及以上版本
+
+* `$data`也就是第一个参数, 可以传入一个[**swoole_websocket_frame**](https://wiki.swoole.com/wiki/page/987.html)对象, 支持发送各种帧类型
+
返回值
----
* 发送成功,返回`true`
diff --git "a/doc/4.4.7 - Coroutine\357\274\217Http\357\274\217Client->addFile.md" "b/doc/4.4.7 - Coroutine\357\274\217Http\357\274\217Client->addFile.md"
index 0d277ec..57ea30c 100644
--- "a/doc/4.4.7 - Coroutine\357\274\217Http\357\274\217Client->addFile.md"
+++ "b/doc/4.4.7 - Coroutine\357\274\217Http\357\274\217Client->addFile.md"
@@ -6,16 +6,16 @@ function Coroutine\Http\Client->addFile(string $path, string $name,
string $mimeType = null, string $filename = null, int $offset = 0, int $length = 0)
```
-* $path 文件的路径,必选参数,不能为空文件或者不存在的文件
-* $name 表单的名称,必选参数,FILES参数中的key
-* $mimeType 文件的MIME格式,可选参数,底层会根据文件的扩展名自动推断
-* $filename 文件名称,可选参数,默认为`basename($path)`
-* $offset 上传文件的偏移量,可以指定从文件的中间部分开始传输数据。此特性可用于支持断点续传。
-* $length 发送数据的尺寸,默认为整个文件的尺寸
+* `$path` 文件的路径,必选参数,不能为空文件或者不存在的文件
+* `$name` 表单的名称,必选参数,`FILES`参数中的`key`
+* `$mimeType` 文件的MIME格式,可选参数,底层会根据文件的扩展名自动推断
+* `$filename` 文件名称,可选参数,默认为`basename($path)`
+* `$offset` 上传文件的偏移量,可以指定从文件的中间部分开始传输数据。此特性可用于支持断点续传。
+* `$length` 发送数据的尺寸,默认为整个文件的尺寸
使用`addFile`会自动将POST的`Content-Type`将变更为`form-data`。`addFile`底层基于`sendfile`,可支持异步发送超大文件。
-> addFile在2.1.2以上可用
+> `addFile`在`2.1.2`以上版本可用
使用示例
----
diff --git "a/doc/4.4.8 - Coroutine\357\274\217Http\357\274\217Client->addData.md" "b/doc/4.4.8 - Coroutine\357\274\217Http\357\274\217Client->addData.md"
new file mode 100644
index 0000000..e731460
--- /dev/null
+++ "b/doc/4.4.8 - Coroutine\357\274\217Http\357\274\217Client->addData.md"
@@ -0,0 +1,31 @@
+# Coroutine\Http\Client->addData
+
+使用字符串构建上传文件内容
+```php
+function Coroutine\Http\Client->addData(string $data, string $name, string $mimeType = null,
+ string $filename = null)
+```
+
+* `$data` 数据内容,必选参数,最大长度不得超过`buffer_output_size`
+* `$name` 表单的名称,必选参数,`$_FILES`参数中的`key`
+* `$mimeType` 文件的`MIME`格式,可选参数,默认为`application/octet-stream`
+* `$filename` 文件名称,可选参数,默认为`$name`
+
+
+使用`addData`会自动将`POST`的`Content-Type`将变更为`form-data`。
+
+> `addData`在`4.1.0`以上版本可用
+
+使用示例
+----
+```php
+$cli = new Swoole\Coroutine\Http\Client('httpbin.org', 80);
+$cli->setHeaders([
+ 'Host' => "httpbin.org"
+]);
+$cli->set(['timeout' => -1]);
+$cli->addData(Co::readFile(__FILE__), 'file1', 'text/plain');
+$cli->post('/post', ['foo' => 'bar']);
+echo $cli->body;
+$cli->close();
+```
\ No newline at end of file
diff --git "a/doc/4.4.8 - Coroutine\357\274\217Http\357\274\217Client->download.md" "b/doc/4.4.9 - Coroutine\357\274\217Http\357\274\217Client->download.md"
similarity index 100%
rename from "doc/4.4.8 - Coroutine\357\274\217Http\357\274\217Client->download.md"
rename to "doc/4.4.9 - Coroutine\357\274\217Http\357\274\217Client->download.md"
diff --git "a/doc/4.5 - Coroutine\357\274\217Http2\357\274\217Client.md" "b/doc/4.5 - Coroutine\357\274\217Http2\357\274\217Client.md"
index dad9d45..29e5aad 100644
--- "a/doc/4.5 - Coroutine\357\274\217Http2\357\274\217Client.md"
+++ "b/doc/4.5 - Coroutine\357\274\217Http2\357\274\217Client.md"
@@ -5,26 +5,26 @@
实例
----
```php
-use Swoole\Coroutine as co;
-
-co::create(function ()
-{
- $cli = new co\Http2\Client('127.0.0.1', 9518);
- $cli->set([ 'timeout' => 1]);
+go(function () {
+ $domain = 'www.zhihu.com';
+ $cli = new Swoole\Coroutine\Http2\Client($domain, 443, true);
+ $cli->set([
+ 'timeout' => -1,
+ 'ssl_host_name' => $domain
+ ]);
$cli->connect();
-
- $req = new co\Http2\Request;
- $req->path = "/index.html";
- $req->headers = [
- 'host' => "localhost",
- "user-agent" => 'Chrome/49.0.2587.3',
- 'accept' => 'text/html,application/xhtml+xml,application/xml',
- 'accept-encoding' => 'gzip',
- ];
- $req->cookies = ['name' => 'rango', 'email' => '1234@qq.com'];
- var_dump($cli->send($req));
- $resp = $cli->recv();
- var_dump($resp);
-
+ $req = new swoole_http2_request;
+ $req->method = 'POST';
+ $req->path = '/api/v4/answers/300000000/voters';
+ $req->headers = [
+ 'host' => $domain,
+ "user-agent" => 'Chrome/49.0.2587.3',
+ 'accept' => 'text/html,application/xhtml+xml,application/xml',
+ 'accept-encoding' => 'gzip'
+ ];
+ $req->data = '{"type":"up"}';
+ $cli->send($req);
+ $response = $cli->recv();
+ assert(json_decode($response->data)->error->code === 602);
});
```
\ No newline at end of file
diff --git "a/doc/4.5.2 - Coroutine\357\274\217Http2\357\274\217Client->set.md" "b/doc/4.5.2 - Coroutine\357\274\217Http2\357\274\217Client->set.md"
index 055f7aa..13f30c0 100644
--- "a/doc/4.5.2 - Coroutine\357\274\217Http2\357\274\217Client->set.md"
+++ "b/doc/4.5.2 - Coroutine\357\274\217Http2\357\274\217Client->set.md"
@@ -1,7 +1,13 @@
# Coroutine\Http2\Client->set
-设置客户端参数,详细配置项请参考 [Client::set 配置选项](https://wiki.swoole.com/wiki/page/p-client_setting.html)
+设置客户端参数,其它详细配置项请参考 [Client::set 配置选项](https://wiki.swoole.com/wiki/page/p-client_setting.html)
```php
function Coroutine\Http2\Client->set(array $options);
+```
+
+```php
+[
+ 'timeout' => 1
+]
```
\ No newline at end of file
diff --git "a/doc/4.5.4 - Coroutine\357\274\217Http2\357\274\217Client->send.md" "b/doc/4.5.4 - Coroutine\357\274\217Http2\357\274\217Client->send.md"
index 2a832b0..5832d1a 100644
--- "a/doc/4.5.4 - Coroutine\357\274\217Http2\357\274\217Client->send.md"
+++ "b/doc/4.5.4 - Coroutine\357\274\217Http2\357\274\217Client->send.md"
@@ -3,16 +3,16 @@
向服务器发送请求,底层会自动建立一个`Http2`的`stream`。可以同时发起多个请求。
```php
-function Coroutine\Http2\Client->send(Coroutine\Http2\Request $request) : int | false
+function Coroutine\Http2\Client->send(swoole_http2_request $request) : int | false
```
-* 接受`Swoole\Coroutine\Http2\Request`类的对象作为参数
+* 接受`swoole_http2_request`类的对象作为参数
* 成功返回流的编号,编号为从`1`开始自增的奇数
* 失败返回`false`
Request对象
-----
-`Swoole\Coroutine\Http2\Request`对象没有任何方法,通过设置对象属性来写入请求相关的信息。
+`swoole_http2_request`对象没有任何方法,通过设置对象属性来写入请求相关的信息。
* `headers` 数组,`HTTP`头
* `method` 字符串,设置请求方法,如`GET`、`POST`
diff --git "a/doc/4.5.6 - Coroutine\357\274\217Http2\357\274\217Client->recv.md" "b/doc/4.5.6 - Coroutine\357\274\217Http2\357\274\217Client->recv.md"
index cd91ed1..0a0905d 100644
--- "a/doc/4.5.6 - Coroutine\357\274\217Http2\357\274\217Client->recv.md"
+++ "b/doc/4.5.6 - Coroutine\357\274\217Http2\357\274\217Client->recv.md"
@@ -3,9 +3,14 @@
接受请求,调用此方法时会`yield`让出协程控制权,服务器返回响应内容后`resume`当前协程。
```php
-function Coroutine\Http2\Client->recv() : Http2\Response
+function Coroutine\Http2\Client->recv(float $timeout) : Http2\Response
```
+### 参数
+`$timeout`: 接收一个任意响应的超时时间
+
+### 返回值
+
成功后返回 [Swoole\Http2\Response](https://wiki.swoole.com/wiki/page/710.html) 对象。
```php
diff --git "a/doc/4.8.2 - Coroutine\357\274\217MySQL->connect.md" "b/doc/4.8.2 - Coroutine\357\274\217MySQL->connect.md"
index 950f7e5..fd98468 100644
--- "a/doc/4.8.2 - Coroutine\357\274\217MySQL->connect.md"
+++ "b/doc/4.8.2 - Coroutine\357\274\217MySQL->connect.md"
@@ -14,10 +14,10 @@ bool connect(array $serverInfo)
'password' => '数据库密码',
'database' => '数据库名',
'port' => 'MySQL端口 默认3306 可选参数',
- 'timeout' => '建立连接超时时间', // 在4.0.4以上, query, prepare, execute,默认使用该值,其次使用传参的值
+ 'timeout' => '建立连接超时时间',
'charset' => '字符集',
'strict_type' => false, //开启严格模式,返回的字段将自动转为数字类型
- 'fetch_more' => true, //开启fetch模式, 可与pdo一样使用fetch/fetchAll逐行或获取全部结果集(4.0版本以上)
+ 'fetch_mode' => true, //开启fetch模式, 可与pdo一样使用fetch/fetchAll逐行或获取全部结果集(4.0版本以上)
]
```
* 返回值:连接建立成功返回`true`,否则返回`false`
diff --git "a/doc/4.8.3 - Coroutine\357\274\217MySQL->query.md" "b/doc/4.8.3 - Coroutine\357\274\217MySQL->query.md"
index 11ab17b..2271b62 100644
--- "a/doc/4.8.3 - Coroutine\357\274\217MySQL->query.md"
+++ "b/doc/4.8.3 - Coroutine\357\274\217MySQL->query.md"
@@ -6,7 +6,6 @@ array|bool query(string $sql, double $timeout = -1)
```
* `$sql`:SQL语句
* `$timeout`:超时时间,`$timeout`如果小于或等于`0`,表示永不超时。在规定的时间内`MySQL`服务器未能返回数据,底层将返回`false`,设置错误码为`110`,并切断连接
-* 在`4.0.4`版本及以上, 默认使用connect时设置的`timeout`, 其次使用`传参的值`
* 返回值:超时/出错返回`false`,否则以数组形式返回查询结果
```php
diff --git "a/doc/4.8.4 - Coroutine\357\274\217MySQL->prepare.md" "b/doc/4.8.4 - Coroutine\357\274\217MySQL->prepare.md"
index 07e63eb..17ad349 100644
--- "a/doc/4.8.4 - Coroutine\357\274\217MySQL->prepare.md"
+++ "b/doc/4.8.4 - Coroutine\357\274\217MySQL->prepare.md"
@@ -12,7 +12,6 @@ function Coroutine\MySQL->prepare(string $sql, float $timeout) : bool
----
* `$sql` 预处理语句,使用`?`作为参数占位符
* `$timeout` 超时时间
-* 在`4.0.4`版本及以上, 默认使用connect时设置的`timeout`, 其次使用`传参的值`
返回值
----
* 失败返回`false`,可检查`$db->error`和`$db->errno`判断错误原因
diff --git "a/doc/4.8.5 - Coroutine\357\274\217MySQL\357\274\217Statement->execute.md" "b/doc/4.8.5 - Coroutine\357\274\217MySQL\357\274\217Statement->execute.md"
index b4aa47f..70a0758 100644
--- "a/doc/4.8.5 - Coroutine\357\274\217MySQL\357\274\217Statement->execute.md"
+++ "b/doc/4.8.5 - Coroutine\357\274\217MySQL\357\274\217Statement->execute.md"
@@ -14,7 +14,6 @@ function Coroutine\MySQL\Statement->execute(array $params, float $timeout = -1)
----
* `$params` 预处理数据参数,必须与`prepare`语句的参数个数相同。`$params`必须为数字索引的数组,参数的顺序与`prepare`语句相同
* `$timeout` 超时时间,在规定的时间内`MySQL`服务器未能返回数据,底层将返回`false`,设置错误码为`110`,并切断连接
-* 在`4.0.4`版本及以上, 默认使用connect时设置的`timeout`, 其次使用`传参的值`
返回值
----
diff --git "a/doc/4.8.6 - Coroutine\357\274\217MySQL\357\274\217Statement->fetch.md" "b/doc/4.8.6 - Coroutine\357\274\217MySQL\357\274\217Statement->fetch.md"
index 8711022..646a773 100644
--- "a/doc/4.8.6 - Coroutine\357\274\217MySQL\357\274\217Statement->fetch.md"
+++ "b/doc/4.8.6 - Coroutine\357\274\217MySQL\357\274\217Statement->fetch.md"
@@ -1,6 +1,6 @@
# Coroutine\MySQL\Statement->fetch
-> Ver >= 4.0-rc1 , 需在connect时加入fetch_more选项
+> Ver >= `4.0-rc1` , 需在`connect`时加入`fetch_mode => true`选项
从结果集中获取下一行
diff --git "a/doc/4.8.7 - Coroutine\357\274\217MySQL\357\274\217Statement->fetchAll.md" "b/doc/4.8.7 - Coroutine\357\274\217MySQL\357\274\217Statement->fetchAll.md"
index 6e51365..6b7de58 100644
--- "a/doc/4.8.7 - Coroutine\357\274\217MySQL\357\274\217Statement->fetchAll.md"
+++ "b/doc/4.8.7 - Coroutine\357\274\217MySQL\357\274\217Statement->fetchAll.md"
@@ -1,6 +1,6 @@
# Coroutine\MySQL\Statement->fetchAll
-> Ver >= 4.0-rc1 , 需在connect时加入fetch_more选项
+> Ver >= `4.0-rc1` , 需在`connect`时加入`fetch_mode => true`选项
返回一个包含结果集中所有行的数组
diff --git "a/doc/4.8.9 - Coroutine\357\274\217MySQL->execFile.md" "b/doc/4.8.9 - Coroutine\357\274\217MySQL->execFile.md"
new file mode 100644
index 0000000..d6b3952
--- /dev/null
+++ "b/doc/4.8.9 - Coroutine\357\274\217MySQL->execFile.md"
@@ -0,0 +1,47 @@
+# Coroutine\MySQL->execFile
+
+这个方法并不存在, 但是可以用PHP代码来实现SQL文件执行, 实际上就是多语句拆分
+
+```php
+function read_sql_file(string $file)
+{
+ $comment_regex = '/(? $line) {
+ if (strlen($line) === 0) {
+ continue;
+ }
+ if (substr($line, -1, 1) !== ';') {
+ if (!$multi) {
+ $multi = true;
+ goto _new_line;
+ } else {
+ _append:
+ $end_line = &$init_sql[count($init_sql) - 1];
+ $end_line = $end_line . $line . "\n";
+ }
+ } else {
+ if ($multi) {
+ $multi = false;
+ goto _append;
+ } else {
+ $multi = false;
+ _new_line:
+ $init_sql[] = "{$line}";
+ }
+ }
+ }
+
+ return $init_sql;
+}
+
+$sql_file = read_sql_file(__DIR__ . '/test.sql');
+foreach ($sql_file as $line) {
+ if (!$mysql->query($line)) {
+ echo "Failed! Error#{$mysql->errno}: {$mysql->error}\n";
+ exit(1);
+ }
+}
+```
\ No newline at end of file
diff --git "a/doc/4.9 - Coroutine\357\274\217PostgreSQL.md" "b/doc/4.9 - Coroutine\357\274\217PostgreSQL.md"
index 4a08c13..26c79b0 100644
--- "a/doc/4.9 - Coroutine\357\274\217PostgreSQL.md"
+++ "b/doc/4.9 - Coroutine\357\274\217PostgreSQL.md"
@@ -2,16 +2,13 @@
启用协程Postgresql客户端
----
-* 需要在编译swoole时增加./configure --enable-coroutine --enable-coroutine-postgresql 来开启此功能
-* 需要确保系统中已安装libpq库
-
-mac安装完postgresq自带libpq库,环境之间有差异,ubuntu可能需要apt-get install libpq-dev
-也可以单独指定libpq库目录如:./configure --enable-coroutine --enable-coroutine-postgresql --with-libpq-dir=/etc/postgresql
-
----
+* 需要在编译`swoole`时增加`./configure --enable-coroutine-postgresql` 来开启此功能
+* 需要确保系统中已安装`libpq`库
+* mac安装完`postgresq`自带`libpq`库,环境之间有差异,`ubuntu`可能需要`apt-get install libpq-dev`
+* 也可以单独指定libpq库目录如:`./configure --enable-coroutine-postgresql --with-libpq-dir=/etc/postgresql`
使用示例
-
+---
```php
go(function () {
$pg = new Swoole\Coroutine\PostgreSQL();
diff --git "a/doc/4.9.1 - Coroutine\357\274\217PostgreSQL->connect.md" "b/doc/4.9.1 - Coroutine\357\274\217PostgreSQL->connect.md"
index 6d3900e..df16ade 100644
--- "a/doc/4.9.1 - Coroutine\357\274\217PostgreSQL->connect.md"
+++ "b/doc/4.9.1 - Coroutine\357\274\217PostgreSQL->connect.md"
@@ -2,7 +2,7 @@
建立postgresql 非阻塞的协程连接
```php
-function Coroutine\PostgreSQL->query(string $connectinfo);
+function Coroutine\PostgreSQL->connect( string $connection_string);
```
example:
diff --git a/doc/5 - AsyncIO.md b/doc/5 - Async.md
similarity index 99%
rename from doc/5 - AsyncIO.md
rename to doc/5 - Async.md
index 1a7fa22..77041a1 100644
--- a/doc/5 - AsyncIO.md
+++ b/doc/5 - Async.md
@@ -1,4 +1,4 @@
-# AsyncIO
+# Async
`1.6.12`版本增加了异步文件读写,异步DNS,异步Http/WebSocket客户端等特性。开发纯异步非阻塞IO的程序时,不能使用`PHP`自带的网络客户端,如`curl`、`file_get_contents`、`stream`、`sockets`、`mysql`、`redis`。
diff --git "a/doc/5.1 - \345\274\202\346\255\245\346\226\207\344\273\266\347\263\273\347\273\237IO.md" "b/doc/5.1 - \345\274\202\346\255\245\346\226\207\344\273\266\347\263\273\347\273\237IO.md"
index 471e5d0..2ff4e17 100644
--- "a/doc/5.1 - \345\274\202\346\255\245\346\226\207\344\273\266\347\263\273\347\273\237IO.md"
+++ "b/doc/5.1 - \345\274\202\346\255\245\346\226\207\344\273\266\347\263\273\347\273\237IO.md"
@@ -1,36 +1,14 @@
# 异步文件系统IO
-Swoole支持2种类型的异步文件读写IO,可以使用`swoole_async_set`来设置AIO模式:.
+ `Swoole`异步文件读写基于线程池同步`IO`模拟实现,文件读写请求投递到任务队列,然后由`AIO`线程读写文件,完成后通知主线程。
-Linux原生异步IO (AIO模式:SWOOLE_AIO_LINUX)
------
-基于Linux Native AIO系统调用,是真正的异步IO,并非阻塞模拟。
+可使用`swoole_async_set`函数设置`AIO`线程数量,提高处理能力。请注意底层会在每个工作进程中分别创建`AIO`线程,因此假设设置了`worker_num = 10`和`thread_num = 10`,将会启动`100`个线程。
-__优点:__
-
-* 所有操作均在一个线程内完成,不需要开线程池
-* 不依赖线程执行IO,所以并发可以非常大
-
-__缺点:__
-
-* 只支持DriectIO,无法利用PageCache,所有对文件读写都会直接操作磁盘
-* 写入数据的size必须为`512`整数倍数
-* 写入数据的offset必须为`512`整数倍数
-
-
-线程池模式异步IO (AIO模式: SWOOLE_AIO_BASE)
------
-基于线程池模拟实现,文件读写请求投递到任务队列,然后由AIO线程读写文件,完成后通知主线程。AIO线程本身是同步阻塞的。所以并非真正的异步IO。
-
-__优点:__
-
-* 可以利用操作系统PageCache,读写热数据性能非常高,等于读内存
-
-> 可修改`thread_num`项设置启用的AIO线程数量
-
-__缺点:__
-
-* 并发较差,不支持同时读写大量文件,最大并发受限与AIO的线程数量
+```php
+swoole_async_set([
+ 'thread_num' => 16,
+]);
+```
冲突问题
----
diff --git a/doc/5.1.5 - swoole_async_dns_lookup.md b/doc/5.1.5 - swoole_async_dns_lookup.md
index 65b5099..abcebdb 100644
--- a/doc/5.1.5 - swoole_async_dns_lookup.md
+++ b/doc/5.1.5 - swoole_async_dns_lookup.md
@@ -1,5 +1,9 @@
# swoole_async_dns_lookup
+> 现在使用swoole任意client都无需使用DNS查询函数, 底层会自动查询:
+
+> [相关文档](https://wiki.swoole.com/wiki/page/821.html)
+
将域名解析为IP地址。调用此函数是非阻塞的,调用会立即返回。将向下执行后面的代码。
* 当DNS查询完成时,自动回调指定的callback函数。
diff --git a/doc/5.2.1 - swoole_event_add.md b/doc/5.2.1 - swoole_event_add.md
index bf20f86..596e6aa 100644
--- a/doc/5.2.1 - swoole_event_add.md
+++ b/doc/5.2.1 - swoole_event_add.md
@@ -1,26 +1,28 @@
# swoole_event_add
- `swoole_event_add`函数用于将一个socket加入到底层的`reactor`事件监听中。此函数可以用在`Server`或`Client`模式下。
-函数原型:
+将一个socket加入到底层的`reactor`事件监听中。此函数可以用在`Server`或`Client`模式下。
+
+函数原型
+---
```php
-bool swoole_event_add(mixed $sock, mixed $read_callback, mixed $write_callback = null,
- int $flags = null);
+bool swoole_event_add(mixed $sock, mixed $read_callback, mixed $write_callback = null,
+ int $flags = null);
```
参数
---
-参数1可以为以下四种类型:
+参数1`$sock` 可以为以下四种类型:
* `int`,就是文件描述符,包括`swoole_client->$sock`、`swoole_process->$pipe`或者其他`fd`
* `stream`资源,就是`stream_socket_client/fsockopen`创建的资源
* `sockets`资源,就是`sockets`扩展中`socket_create`创建的资源,需要在编译时加入 `./configure --enable-sockets`
* `object`,`swoole_process`或`swoole_client`,底层自动转换为管道或客户端连接的`socket`
-参数`2`为可读回调函数,参数`3`为可写事件回调,可以是字符串函数名、对象+方法、类静态方法或匿名函数,当此`socket`可读时回调指定的函数。
+参数2`$read_callback`为可读事件回调函数,参数3`$write_callback`为可写事件回调函数,此参数可以是字符串函数名、对象+方法、类静态方法或匿名函数,当此`socket`可读或者可写时回调指定的函数。
-参数`4`为事件类型的掩码,可选择关闭/开启可读可写事件,如`SWOOLE_EVENT_READ`,`SWOOLE_EVENT_WRITE`,或者`SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE`
+参数4`$flags`为事件类型的掩码,可选择关闭/开启可读可写事件,如`SWOOLE_EVENT_READ`,`SWOOLE_EVENT_WRITE`,或者`SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE`
```
diff --git a/doc/5.2.7 - swoole_event_defer.md b/doc/5.2.7 - swoole_event_defer.md
index d14599b..04987e5 100644
--- a/doc/5.2.7 - swoole_event_defer.md
+++ b/doc/5.2.7 - swoole_event_defer.md
@@ -4,10 +4,11 @@
```php
swoole_event_defer(mixed $callback_function);
```
-swoole_event_defer函数会在当前EventLoop的事件循环结束、下一次事件循环启动时响应
+`swoole_event_defer`的回调函数会在当前`EventLoop`的事件循环结束、下一次事件循环开始前执行。
-* $callback_function 时间到期后所执行的函数,必须是可以调用的。回调函数不接受任何参数
+* `$callback_function` 时间到期后所执行的函数,必须是可以调用的。回调函数不接受任何参数
* 可以使用匿名函数的`use`语法传递参数到回调函数中
+* 在`$callback_function`函数执行过程中添加新的`defer`任务,仍然会在本轮事件循环内执行完成
使用示例
----
diff --git "a/doc/5.3 - \345\274\202\346\255\245\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md" "b/doc/5.3 - \345\274\202\346\255\245\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md"
index 2f0137a..a909a59 100644
--- "a/doc/5.3 - \345\274\202\346\255\245\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md"
+++ "b/doc/5.3 - \345\274\202\346\255\245\346\257\253\347\247\222\345\256\232\346\227\266\345\231\250.md"
@@ -1,13 +1,27 @@
# 异步毫秒定时器
-swoole_server中已经提供了定时器的API,如果是在客户端程序中,也想使用毫秒定时器。可以用swoole提供的swoole_timer模块。
+毫秒精度的定时器。底层基于`epoll_wait`和`setitimer`实现,数据结构使用`最小堆`,可支持添加大量定时器。
-swoole_timer与PHP本身的pcntl_alarm是不同的。pcntl_alarm是基于时钟信号 + PHP tick函数实现,有4个缺陷:
+> 无法用于`Manager`管理进程中
-* 最大仅支持到秒,而swoole_timer可以到毫秒级别
+
+性能
+----
+底层使用最小堆数据结构实现定时器,定时器的添加和删除,全部为内存操作,因此性能是非常高的。官方的基准测试脚本 中,添加或删除`10万`个随机时间的定时器耗时为`0.08s`左右。
+
+```shell
+~/workspace/swoole/benchmark$ php timer.php
+add 100000 timer :0.091133117675781s
+del 100000 timer :0.084658145904541s
+```
+
+差异
+-----
+`swoole_timer`与`PHP`本身的`pcntl_alarm`是不同的。`pcntl_alarm`是基于时钟信号 + PHP tick函数实现,有5个缺陷:
+
+* 最大仅支持到秒,而`swoole_timer`可以到毫秒级别
* 不支持同时设定多个定时器程序
-* pcntl_alarm依赖declare(ticks = 1)性能很差
-* 无法用于异步IO,只支持同步方式
+* `pcntl_alarm`依赖`declare(ticks = 1)`,性能很差
+* 无法用于异步`IO`,只支持同步方式。
-swoole_timer是基于timerfd+epoll实现的异步毫秒定时器,可完美的运行在EventLoop中,与swoole_client/swoole_event等模块可以无缝结合。
diff --git a/doc/5.3.1 - swoole_timer_tick.md b/doc/5.3.1 - swoole_timer_tick.md
index 7fd7b8f..4c304aa 100644
--- a/doc/5.3.1 - swoole_timer_tick.md
+++ b/doc/5.3.1 - swoole_timer_tick.md
@@ -1,24 +1,22 @@
# swoole_timer_tick
-设置一个间隔时钟定时器,与after定时器不同的是tick定时器会持续触发,直到调用swoole_timer_clear清除。
+设置一个间隔时钟定时器,与`after`定时器不同的是`tick`定时器会持续触发,直到调用`swoole_timer_clear`清除。
```php
-int swoole_timer_tick(int $ms, callable $callback, mixed $user_param);
+int swoole_timer_tick(int $msec, callable $callback);
```
-* $ms 指定时间,单位为毫秒
-* $callback_function 时间到期后所执行的函数,必须是可以调用的。
-* $user_param 用户参数, 该参数会被传递到`$callback_function`中. 如果有多个参数可以使用数组形式. 也可以使用匿名函数的`use`语法传递参数到回调函数中
+* `$msec` 指定时间,单位为毫秒。如`1000`表示`1秒`,最大不得超过 `86400000`
+* `$callback_function` 时间到期后所执行的函数,必须是可以调用的
+* 可以使用匿名函数的`use`语法传递参数到回调函数中
* 定时器仅在当前进程空间内有效
* 定时器是纯异步实现的,不能与阻塞IO的函数一起使用,否则定时器的执行时间会发生错乱
-> $ms 最大不得超过 86400000
-> tick定时器在1.7.14以上版本可用
-> 定时器在执行的过程中可能会产生微小的偏差,请勿基于定时器实现精确时间计算
+> 定时器在执行的过程中可能存在一定误差
回调函数
----
-定时器触发的回调函数接受2个参数。
+定时器触发的回调函数接受`2`个参数。
```php
function callbackFunction(int $timer_id, mixed $params = null);
@@ -29,9 +27,9 @@ function callbackFunction(int $timer_id, mixed $params = null);
定时器校正
----
-定时器回调函数的执行时间不影响下一次定时器执行的时间。实例:在`0.002ms`设置了`10ms`的`tick`定时器,第一次会在`0.012ms`执行回调函数,如果回调函数执行了`5ms`,下一次定时器仍然会在`0.022ms`时触发,而不是`0.027ms`。
+定时器回调函数的执行时间不影响下一次定时器执行的时间。实例:在`0.002s`设置了`10ms`的`tick`定时器,第一次会在`0.012s`执行回调函数,如果回调函数执行了`5ms`,下一次定时器仍然会在`0.022s`时触发,而不是`0.027s`。
-但如果定时器回调函数的执行时间过长,甚至覆盖了下一次定时器执行的时间。底层会进行时间校正,丢弃已过期的行为,在下一时间回调。如上面例子中`0.012ms`时的回调函数执行了`15ms`,本该在`0.022ms`产生一次定时回调。实际上本次定时器在`0.027ms`才返回,这时定时早已过期。底层会在`0.032ms`时再次触发定时器回调。
+但如果定时器回调函数的执行时间过长,甚至覆盖了下一次定时器执行的时间。底层会进行时间校正,丢弃已过期的行为,在下一时间回调。如上面例子中`0.012s`时的回调函数执行了`15ms`,本该在`0.022s`产生一次定时回调。实际上本次定时器在`0.027s`才返回,这时定时早已过期。底层会在`0.032s`时再次触发定时器回调。
使用示例
----
@@ -59,8 +57,3 @@ swoole_timer_tick(3000, function () {
echo "after 14000ms.\n";
});
```
-
-
-注意
-----
-如果需要在Swoole Server内使用此功能,请用swoole_server->tick
\ No newline at end of file
diff --git a/doc/5.3.2 - swoole_timer_after.md b/doc/5.3.2 - swoole_timer_after.md
index 88b4c19..6639f0d 100644
--- a/doc/5.3.2 - swoole_timer_after.md
+++ b/doc/5.3.2 - swoole_timer_after.md
@@ -2,7 +2,7 @@
在指定的时间后执行函数,需要`1.7.7`或更高版本。
```php
-int swoole_timer_after(int $after_time_ms, mixed $callback_function, mixed $user_param);
+int swoole_timer_after(int $after_time_ms, mixed $callback_function);
```
`swoole_timer_after`函数是一个一次性定时器,执行完成后就会销毁。此函数与`PHP`标准库提供的`sleep`函数不同,`after`是非阻塞的。而`sleep`调用后会导致当前的进程进入阻塞,将无法处理新的请求。
@@ -10,22 +10,12 @@ int swoole_timer_after(int $after_time_ms, mixed $callback_function, mixed $user
* `$after_time_ms` 指定时间,单位为毫秒,最大不得超过 `86400000`
* `$callback_function` 时间到期后所执行的函数,必须是可以调用的。
-* `$user_param` 用户参数, 该参数会被传递到`$callback_function`中. 如果有多个参数可以使用数组形式. 也可以使用匿名函数的`use`语法传递参数到回调函数中
+* 可以使用匿名函数的`use`语法传递参数到回调函数中
使用示例
----
```php
-swoole_timer_after(1000, function(){
- echo "timeout\n";
+swoole_timer_after(1000, function() use ($str) {
+ echo "timeout, $str\n";
});
```
-
-性能测试
-----
-底层使用最小堆数据结构实现定时器,定时器的添加和删除,全部为内存操作,因此性能是非常高的。官方的基准测试脚本 中,添加或删除`10万`个随机时间的定时器耗时为`0.08s`左右。
-
-```shell
-~/workspace/swoole/benchmark$ php timer.php
-add 100000 timer :0.091133117675781s
-del 100000 timer :0.084658145904541s
-```
\ No newline at end of file
diff --git a/doc/5.3.3 - swoole_timer_clear.md b/doc/5.3.3 - swoole_timer_clear.md
index d918d48..8b22861 100644
--- a/doc/5.3.3 - swoole_timer_clear.md
+++ b/doc/5.3.3 - swoole_timer_clear.md
@@ -1,13 +1,13 @@
# swoole_timer_clear
-使用定时器ID来删除定时器。
+使用定时器`ID`来删除定时器。
```php
bool swoole_timer_clear(int $timer_id)
```
-* $timer_id,定时器ID,调用`swoole_timer_tick`、`swoole_timer_after`后会返回一个整数的ID
-* swoole_timer_clear不能用于清除其他进程的定时器,只作用于当前进程
+* `$timer_id`,定时器ID,调用`swoole_timer_tick`、`swoole_timer_after`后会返回一个整数的ID
+* `swoole_timer_clear`不能用于清除其他进程的定时器,只作用于当前进程
使用示例
----
diff --git "a/doc/5.4 - \345\274\202\346\255\245MySQL\345\256\242\346\210\267\347\253\257.md" "b/doc/5.4 - \345\274\202\346\255\245MySQL\345\256\242\346\210\267\347\253\257.md"
index 5e16211..6a1d9f0 100644
--- "a/doc/5.4 - \345\274\202\346\255\245MySQL\345\256\242\346\210\267\347\253\257.md"
+++ "b/doc/5.4 - \345\274\202\346\255\245MySQL\345\256\242\346\210\267\347\253\257.md"
@@ -7,7 +7,7 @@
使用实例
---
```php
-$db = new swoole_mysql;
+$db = new swoole_mysql();
$server = array(
'host' => '192.168.56.102',
'port' => 3306,
diff --git a/doc/5.4.1 - swoole_mysql->construct.md b/doc/5.4.1 - swoole_mysql->__construct.md
similarity index 51%
rename from doc/5.4.1 - swoole_mysql->construct.md
rename to doc/5.4.1 - swoole_mysql->__construct.md
index 02ce7db..22d49e1 100644
--- a/doc/5.4.1 - swoole_mysql->construct.md
+++ b/doc/5.4.1 - swoole_mysql->__construct.md
@@ -1,3 +1,3 @@
-# swoole_mysql->construct
+# swoole_mysql->__construct
创建异步mysql客户端。
\ No newline at end of file
diff --git a/doc/5.4.6 - swoole_mysql->begin.md b/doc/5.4.6 - swoole_mysql->begin.md
index 598b356..d4ea8ec 100644
--- a/doc/5.4.6 - swoole_mysql->begin.md
+++ b/doc/5.4.6 - swoole_mysql->begin.md
@@ -18,7 +18,7 @@ function swoole_mysql->begin(callable $callback);
```php
$db->begin(function( $db, $result) {
$db->query("update userinfo set level = 22 where id = 1", function($db, $result) {
- $db->rollback(function($db, $result) {
+ $db->commit(function($db, $result) {
echo "commit ok\n";
});
});
diff --git "a/doc/5.5 - \345\274\202\346\255\245Redis\345\256\242\346\210\267\347\253\257.md" "b/doc/5.5 - \345\274\202\346\255\245Redis\345\256\242\346\210\267\347\253\257.md"
index 4548229..3cf7555 100644
--- "a/doc/5.5 - \345\274\202\346\255\245Redis\345\256\242\346\210\267\347\253\257.md"
+++ "b/doc/5.5 - \345\274\202\346\255\245Redis\345\256\242\346\210\267\347\253\257.md"
@@ -15,6 +15,8 @@ sudo ldconfig
启用异步Redis客户端
----
+> 4.2.x 中 `redis-client` 即是 异步redis客户端开启, 并非无法开启, 以实际使用为准
+
编译swoole时,在`configure`指令中加入`--enable-async-redis`
```shell
./configure --enable-async-redis
@@ -22,9 +24,10 @@ make clean
make -j
sudo make install
```
+
可能遇到的问题
----
-`php-m` 发现swoole消失或者是通过`php --ri swoole`没有显示async redis client
+`php-m` 发现swoole消失或者是通过`php --ri swoole`没有显示`async redis client` 或 `redis client`
```shell
vi ~/.bash_profile
在最后一行添加 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
diff --git a/doc/5.5.3 - swoole_redis->connect.md b/doc/5.5.3 - swoole_redis->connect.md
index f22adbb..3d8a40a 100644
--- a/doc/5.5.3 - swoole_redis->connect.md
+++ b/doc/5.5.3 - swoole_redis->connect.md
@@ -28,7 +28,7 @@ function onConnect(swoole_redis $redis, bool $result);
$client = new swoole_redis;
$client->connect('127.0.0.1', 6379, function (swoole_redis $client, $result) {
if ($result === false) {
- echo "connect to redis server failed.\n"
+ echo "connect to redis server failed.\n";
return;
}
$client->set('key', 'swoole', function (swoole_redis $client, $result) {
diff --git a/doc/5.6.1 - swoole_http_client->__construct.md b/doc/5.6.1 - swoole_http_client->__construct.md
index 80eef31..05342da 100644
--- a/doc/5.6.1 - swoole_http_client->__construct.md
+++ b/doc/5.6.1 - swoole_http_client->__construct.md
@@ -15,17 +15,15 @@ swoole_http_client->__construct(string $host, int port, bool $ssl = false);
使用示例
----
```php
-Swoole\Async::dnsLookup("www.baidu.com", function ($domainName, $ip) {
- $cli = new swoole_http_client($ip, 80);
- $cli->setHeaders([
- 'Host' => $domainName,
- "User-Agent" => 'Chrome/49.0.2587.3',
- 'Accept' => 'text/html,application/xhtml+xml,application/xml',
- 'Accept-Encoding' => 'gzip',
- ]);
- $cli->get('/index.html', function ($cli) {
- echo "Length: " . strlen($cli->body) . "\n";
- echo $cli->body;
- });
+$cli = new swoole_http_client('www.baidu.com', 80);
+$cli->setHeaders([
+ 'Host' => $domainName,
+ "User-Agent" => 'Chrome/49.0.2587.3',
+ 'Accept' => 'text/html,application/xhtml+xml,application/xml',
+ 'Accept-Encoding' => 'gzip',
+]);
+$cli->get('/index.html', function ($cli) {
+ echo "Length: " . strlen($cli->body) . "\n";
+ echo $cli->body;
});
```
\ No newline at end of file
diff --git a/doc/5.6.14 - swoole_http_client->close.md b/doc/5.6.14 - swoole_http_client->close.md
index d5de7a6..5059c2c 100644
--- a/doc/5.6.14 - swoole_http_client->close.md
+++ b/doc/5.6.14 - swoole_http_client->close.md
@@ -1,9 +1,20 @@
# swoole_http_client->close
-关闭连接,函数原型为:
+关闭连接
+
+函数原型
+---
```php
-function swoole_http_client->close() : bool
+bool swoole_http_client->close()
```
+参数
+---
+无
+
+返回值
+----
操作成功返回 **true**
-> `swoole_http_client`与普通的`swoole_client`不同,`close`后如果再次请求`get`、`post`等方法时,底层会重新连接服务器
\ No newline at end of file
+注意事项
+---
+- `swoole_http_client` 与普通的 `swoole_client` 不同,`close` 后如果再次请求 `get`、`post` 等方法时,底层会重新连接服务器
\ No newline at end of file
diff --git a/doc/6.3.1 - swoole_table->__construct.md b/doc/6.3.1 - swoole_table->__construct.md
index d6bbe1f..7197962 100644
--- a/doc/6.3.1 - swoole_table->__construct.md
+++ b/doc/6.3.1 - swoole_table->__construct.md
@@ -7,7 +7,7 @@ swoole_table->__construct(int $size, float $conflict_proportion = 0.2)
* `$size`参数指定表格的最大行数,如果`$size`不是为`2`的N次方,如`1024`、`8192`,`65536`等,底层会自动调整为接近的一个数字,如果小于1024则默认成1024,即1024是最小值
* `table`占用的内存总数为 (结构体长度 + KEY长度64字节 + 行尺寸`$size`) * (1.2预留20%作为hash冲突) * (列尺寸),如果机器内存不足table会创建失败
-* `set`操作能存储的最大行数与`$size`无关,如`$size`为1024实际可存储的行数小于`1024`
+* `set`操作能存储的最大行数与`$size`正相关,但不完全一致,如`$size`为1024实际可存储的行数小于`1024`
> swoole_table基于行锁,所以单次set/get/del在多线程/多进程的环境下是安全的
diff --git a/doc/6.3.4 - swoole_table->set.md b/doc/6.3.4 - swoole_table->set.md
index cf507a2..24f818f 100644
--- a/doc/6.3.4 - swoole_table->set.md
+++ b/doc/6.3.4 - swoole_table->set.md
@@ -5,12 +5,13 @@
swoole_table->set(string $key, array $value)
```
-* $key,数据的key,相同的$key对应同一行数据,如果set同一个key,会覆盖上一次的数据
-* $value,必须是一个数组,必须与字段定义的$name完全相同
+* `$key`,数据的`key`,相同的`$key`对应同一行数据,如果`set`同一个`key`,会覆盖上一次的数据
+* `$value`,必须是一个数组,必须与字段定义的`$name`完全相同
-> swoole_table->set() 可以设置全部字段的值,也可以只修改部分字段
-> swoole_table->set() 未设置前,该行数据的所有字段均为空
-> set/get/del 是自带行锁,所以不需要调用lock加锁
+> `swoole_table->set()` 可以设置全部字段的值,也可以只修改部分字段
+> `swoole_table->set()` 未设置前,该行数据的所有字段均为空
+> `set/get/del` 是自带行锁,所以不需要调用lock加锁
+> **Key非二进制安全,必须为字符串类型,不得传入二进制数据**
```php
$table->set('1', ['id' => 1, 'name' => 'test1', 'age' => 20]);
diff --git a/doc/6.3.9 - swoole_table->del.md b/doc/6.3.9 - swoole_table->del.md
index b7143ea..2bd179c 100644
--- a/doc/6.3.9 - swoole_table->del.md
+++ b/doc/6.3.9 - swoole_table->del.md
@@ -5,6 +5,8 @@
bool swoole_table->del(string $key)
```
-* $key对应的数据不存在,将返回false
-* 成功删除返回true
+* `$key`对应的数据不存在,将返回`false`
+* 成功删除返回`true`
+
+> **Key非二进制安全,必须为字符串类型,不得传入二进制数据**
diff --git a/doc/8 - HttpServer.md b/doc/8 - HttpServer.md
index 5dd9ccc..d1d8073 100644
--- a/doc/8 - HttpServer.md
+++ b/doc/8 - HttpServer.md
@@ -1,6 +1,5 @@
# HttpServer
-
> **swoole_http_server对Http协议的支持并不完整,建议仅作为应用服务器。并且在前端增加Nginx作为代理**
swoole-1.7.7增加了内置Http服务器的支持,通过几行代码即可写出一个异步非阻塞多进程的Http服务器。
@@ -22,8 +21,8 @@ ab -c 200 -n 200000 -k http://127.0.0.1:9501
使用Http2协议
----
* 需要依赖`nghttp2`库,[下载nghttp2](https://github.com/tatsuhiro-t/nghttp2)后编译安装
-* 使用`Http2`协议必须开启`openssl`
-* 需要高版本`openssl`必须支持`TLS1.2`、`ALPN`、`NPN`
+* 使用SSL下的`Http2`协议必须安装`openssl`, 且需要高版本`openssl`必须支持`TLS1.2`、`ALPN`、`NPN`
+* 使用HTTP2不一定要开启SSL
```shell
./configure --enable-openssl --enable-http2
diff --git a/doc/8.3.1 - swoole_http_response->header.md b/doc/8.3.1 - swoole_http_response->header.md
index 1ee60ea..4001340 100644
--- a/doc/8.3.1 - swoole_http_response->header.md
+++ b/doc/8.3.1 - swoole_http_response->header.md
@@ -10,7 +10,7 @@ function swoole_http_response->header(string $key, string $value, bool $ucwords
----
* `$key`,`Http`头的`Key`
* `$value`,`Http`头的`Value`
-* `$ucwords` 是否需要对Key进行Http约定格式化,默认`true`会自动格式化
+* `$ucwords` 是否需要对`Key`进行`Http`约定格式化,默认`true`会自动格式化
返回值
----
@@ -29,8 +29,8 @@ function swoole_http_response->header(string $key, string $value, bool $ucwords
示例
---
```php
-$response->header('Content-Type', 'image/jpeg',false);
-$response->header('content-type', 'image/jpeg',true);
+$response->header('Content-Type', 'image/jpeg', false);
+$response->header('content-type', 'image/jpeg', true);
```
diff --git a/doc/8.3.10 - swoole_http_response::create.md b/doc/8.3.10 - swoole_http_response::create.md
index 6296d36..170c35e 100644
--- a/doc/8.3.10 - swoole_http_response::create.md
+++ b/doc/8.3.10 - swoole_http_response::create.md
@@ -16,7 +16,7 @@ $http = new swoole_http_server("0.0.0.0", 9501);
$http->on('request', function ($req, Swoole\Http\Response $resp) use ($http) {
$resp->detach();
- $resp2 = Swoole\Http\Response::create($data);
+ $resp2 = Swoole\Http\Response::create($req->fd);
$resp2->end("hello world");
});
diff --git a/doc/8.3.4 - swoole_http_response->gzip.md b/doc/8.3.4 - swoole_http_response->gzip.md
index 3725fe8..af74460 100644
--- a/doc/8.3.4 - swoole_http_response->gzip.md
+++ b/doc/8.3.4 - swoole_http_response->gzip.md
@@ -1,5 +1,15 @@
# swoole_http_response->gzip
+废弃
+---
+> 此函数在 4.1.0 或更高版本中已废弃, 请移步[http_compression](https://wiki.swoole.com/wiki/page/973.html)
+
+在新版本中使用`http_compression`配置项取代了`gzip`方法。主要原因是`gzip()`方法未判断浏览器客户端传入的`Accept-Encoding`头,如果客户端不支持`gzip`压缩,强行使用会导致客户端无法解压。
+
+全新的`http_compression`配置项会根据客户端`Accept-Encoding`头,自动选择是否压缩,并自动选择最佳的压缩算法。
+
+函数原型
+----
启用`Http GZIP`压缩。压缩可以减小`HTML`内容的尺寸,有效节省网络带宽,提高响应时间。必须在`write/end`发送内容之前执行`gzip`,否则会抛出错误。
```php
diff --git a/doc/8.4.4 - http_compression.md b/doc/8.4.4 - http_compression.md
new file mode 100644
index 0000000..ecda6ac
--- /dev/null
+++ b/doc/8.4.4 - http_compression.md
@@ -0,0 +1,22 @@
+# http_compression
+
+启用压缩。默认为开启。
+
+http-chunk不支持分段单独压缩, 已强制关闭压缩.
+
+```php
+$sever->set([
+ 'http_compression' => true,
+]);
+```
+
+目前支持`gzip`、`br`、`deflate` 三种压缩格式,底层会根据浏览器客户端传入的`Accept-Encoding`头自动选择压缩方式。
+
+> `http_compression`在`4.1.0`或更高版本可用
+> `br`压缩格式需要`google brotli`库
+
+## http_compression_level
+
+或`http_gzip_level`
+
+压缩的级别, 越高压缩后体积越小, 也越占用CPU
\ No newline at end of file
diff --git a/doc/9.1.3 - onMessage.md b/doc/9.1.3 - onMessage.md
index e28c749..a4878e0 100644
--- a/doc/9.1.3 - onMessage.md
+++ b/doc/9.1.3 - onMessage.md
@@ -3,7 +3,7 @@
当服务器收到来自客户端的数据帧时会回调此函数。
```php
-function onMessage(swoole_server $server, swoole_websocket_frame $frame)
+function onMessage(swoole_websocket_server $server, swoole_websocket_frame $frame)
```
* $frame 是swoole_websocket_frame对象,包含了客户端发来的数据帧信息
diff --git a/doc/9.2.1 - swoole_websocket_server->push.md b/doc/9.2.1 - swoole_websocket_server->push.md
index 4e68c58..c337b8a 100644
--- a/doc/9.2.1 - swoole_websocket_server->push.md
+++ b/doc/9.2.1 - swoole_websocket_server->push.md
@@ -1,14 +1,22 @@
# swoole_websocket_server->push
+> swoole_websocket_server->push在swoole-1.7.11以上版本可用
+
向websocket客户端连接推送数据,长度最大不得超过2M。
```php
-function swoole_websocket_server->push(int $fd, string $data, int $opcode = 1, bool $finish = true);
+function swoole_websocket_server->push(int $fd, $data, int $opcode = 1, bool $finish = true);
```
+参数模式1
+----
* $fd 客户端连接的ID,如果指定的$fd对应的TCP连接并非websocket客户端,将会发送失败
* $data 要发送的数据内容
* $opcode,指定发送数据内容的格式,默认为文本。发送二进制内容$opcode参数需要设置为`WEBSOCKET_OPCODE_BINARY`
* 发送成功返回true,发送失败返回false
-> swoole_websocket_server->push在swoole-1.7.11以上版本可用
+参数模式2
+----
+> 需要4.2.0及以上版本
+
+* `$data`也就是第一个参数, 可以传入一个[**swoole_websocket_frame**](https://wiki.swoole.com/wiki/page/987.html)对象, 支持发送各种帧类型
diff --git "a/doc/9.5 - \351\205\215\347\275\256\351\200\211\351\241\271.md" "b/doc/9.5 - \351\205\215\347\275\256\351\200\211\351\241\271.md"
index 0caebe4..f71e992 100644
--- "a/doc/9.5 - \351\205\215\347\275\256\351\200\211\351\241\271.md"
+++ "b/doc/9.5 - \351\205\215\347\275\256\351\200\211\351\241\271.md"
@@ -10,4 +10,31 @@
$server->set([
'websocket_subprotocol' => 'chat',
]);
+```
+
+open_websocket_close_frame
+----
+启用websocket协议中关闭帧(opcode为0x08的帧)在onMessage回调中接收,默认为false。
+
+开启后,可在WebSocketServer中的``onMessage``回调中接收到客户端或服务端发送的关闭帧,开发者可自行对其进行处理。
+
+示例:
+```php
+$server = new swoole_websocket_server("0.0.0.0", 9501);
+
+$server->set(array("open_websocket_close_frame" => true));
+
+$server->on('open', function (swoole_websocket_server $server, $request) {});
+
+$server->on('message', function (swoole_websocket_server $server, $frame) {
+ if ($frame->opcode == 0x08) {
+ echo "Close frame received: Code {$frame->code} Reason {$frame->reason}\n";
+ } else {
+ echo "Message received: {$frame->data}\n";
+ }
+});
+
+$server->on('close', function ($ser, $fd) {});
+
+$server->start();
```
\ No newline at end of file
diff --git a/doc/9.6 - swoole_websocket_frame.md b/doc/9.6 - swoole_websocket_frame.md
new file mode 100644
index 0000000..d809679
--- /dev/null
+++ b/doc/9.6 - swoole_websocket_frame.md
@@ -0,0 +1,43 @@
+# swoole_websocket_frame
+
+在Swoole 4.2.0版本中, 新增了 服务端和客户端 发送`swoole_websocket_frame`对象的支持
+
+同时增加了一个新的子类`swoole_websocket_close_frame`
+
+一个普通的frame对象具有以下属性
+```php
+object(Swoole\WebSocket\Frame)#1 (4) {
+ ["fd"]=>
+ int(0)
+ ["data"]=>
+ NULL
+ ["opcode"]=>
+ int(1)
+ ["finish"]=>
+ bool(true)
+}
+```
+
+一个普通的close frame对象具有以下属性, 多了`code`和`reason`属性, 记录了关闭的错误代码和原因
+
+如果服务端需要接收close_frame, 需要通过`$server->set`开启`open_websocket_close_frame`参数
+```php
+object(Swoole\WebSocket\CloseFrame)#1 (6) {
+ ["fd"]=>
+ int(0)
+ ["data"]=>
+ NULL
+ ["finish"]=>
+ bool(true)
+ ["opcode"]=>
+ int(8)
+ ["code"]=>
+ int(1000)
+ ["reason"]=>
+ string(0) ""
+}
+```
+
+在用于发送时, fd属性会被忽略(因为服务器端fd是第一个参数, 客户端无需指定fd), 所以fd是一个只读属性
+
+相关示例代码可以在 [swoole websocket 单元测试](https://github.com/swoole/swoole-src/tree/master/tests/swoole_websocket_server) 中找到
\ No newline at end of file