4.2.13
修复(需注意的不兼容变更)
- 修复Redis订阅模式API设计问题导致重复订阅和订阅消息丢失的问题 (详见: 订阅模式文档 或 附录示例代码) (#2305) (@windrunner414)
- 使用协程化时, 不能再
pconnect
等传统连接复用的方法, 否则会产生多协程同时复用同一个Socket的问题 (7b1e786) (@shiguangqi)
增强
- 协程客户端支持全双工 (#2350) (@twosee)
- 支持安全的跨协程close (#2327) (@twosee)
- RFC-1015: 非Worker进程允许单向投递任务 (222043a) (@matyhtf)
swoole_strerror
支持自动转换系统错误码和Swoole底层错误码为文字, 无需指定参数 (c92f444) (@twosee)
- gdb追踪工具支持查看定时器和reactor信息 (2beb563) (@shiguangqi)
- 使用Redis集群时出现MOVED和ASK错误时将自动转移到对应服务端 (#2299) (@windrunner414)
- 底层代码优化, 减少收包时的内存拷贝 (@matyhtf)
- 现在调用
Co\Socket->close()
将会立即close fd, 而非等待对象析构后close, close后调用其它任何API将返回BADF错误 (和系统API保持一致) (7a61963) (@twosee)
- 一些非法的参数不再会导致致命错误而是产生一个警告, 因为外部传参有时不可控, 存在一定风险 (cd432d3) (@twosee)
- 使用协程化后API兼容性增强(和同步阻塞表现一致) (36687e8) (@matyhtf)
- 现在swoole\src可以同时作为C\C++库使用(libswoole)
修复
- 修复初次加载前存在大量对象时可能的coredump问题 (4ddeedb) (@twosee)
- 修复没有DNS缓存时尝试清除缓存导致的coredump (#2288) (@mabu233)
- 启用
task_enable_coroutine
后, 错误地调用Server->finish
会触发致命错误 (156ede6) (@twosee)
- 现在php.ini配置指定
On
和Off
时能正确显示(而不是显示0) (fe25982) (@twosee)
- 修复
Co::getaddrinfo
后几个参数接收错误的BUG (#2273) (@mabu233)
- 修复dispatch_func在UDP模式下时fd错误的问题 (#2306) (@mabu233)
- 修复dispatch_func在指定函数名时不生效的BUG, 回调在未接收包体数据参数时减少内存拷贝(如基于fd分配的模式) (2bc49e4) (@twosee)
- Task过期时将不再触发PHP警告(而是swoole底层的日志警告) (54eee5e) (@matyhtf)
- 修复进程重启时enable_coroutine失效问题 (#2310)
- 修复进程id属性不正确的问题 (#2313) (@junwei-qu)
- 修复BASE模式下错误地在onStart回调中使用异步API导致的问题 (#2308) (@matyhtf)
- 修复BASE模式下manager_id不正确 (e18e013) (@matyhtf )
- 修复mmap使用SEEK_END偏移错误 (#2314) (@junwei-qu)
- 修复getSocket内存泄漏 (ec8c4b2) (@twosee)
- 优化stream模式 (47e0e9e) (@matyhtf )
- 修复同步客户端KEEP模式下连接复用在某些情况下导致的BUG (4c5728b) (@matyhtf)
- 修复MacOS下
Atmoic
多次wait
和wakeup
溢出的问题 (fbccb25) (@twosee)
- 修复开启static_handler存在目录遍历攻击风险的问题, 这是一个便利性调试功能, 请勿用于生产 (#2323) (@windrunner414)
- 修复未检查futex_wait系统调用的返回值 (#2351) (@junwei-qu)
- 修复Reids::ZAdd API解析参数的BUG, 并修复其它潜在的类型转换问题 (#2321) (21e0497) (a0e612f) (00134cf) (f5a331e) (5f87f17) (a15f094) (67f3285) (808f578) (d118fe3) (5294473) (48f6790) (0105c7f) (ba6c8b4) (@matyhtf)
- 修复发送数据时没有使用函数指针可能导致的第三方hook失败 (89ba2da) (@matyhtf )
- 兼容性: Mysql escape方法出错时将返回空字符串而不是FALSE
- 修复Timer::tick方法有传参时产生的内存泄露 (7e15141) (@mabu233)
- 修复自定义进程不能自动退出 (2901ce0) (@matyhtf)
- 修复协程化后连接超时时间影响到读操作超时时间 (a990540) (@shiguangqi)
- 修复
Co\Client
指定收包规则后, 传参超时时间不生效的问题 (#2346) (@twosee)
- Server在BASE模式下不再受
buffer_output_size
限制, 仅受socket_buffer_size
限制 (#2326) (@matyhtf)
- 修复在FREEBSD下的编译错误 (#2325) (@matyhtf)
单元测试
- 更多的单元测试
- 新增内存测试到valgrind分支, 分离alpine测试到alpine分支, 自动触发测试
- 测试支持在任意装有docker的主机上运行并自动部署基于docker的swoole/mysql/redis容器, 详情参阅源码目录下travis文件夹内的README文档
其它
- Swoole\Serialize现已支持在PHP73下正常运作, 但仍标记为待废除的功能, 不建议使用
附录
协程Redis订阅模式示例代码:
$redis = new Swoole\Coroutine\Redis();
$redis->connect('127.0.0.1', 6379);
if ($redis->subscribe(['channel1', 'channel2', 'channel3'])) // 或者使用psubscribe
{
while ($msg = $redis->recv()) {
// msg是一个数组, 包含以下信息
// $type # 返回值的类型:显示订阅成功
// $name # 订阅的频道名字 或 来源频道名字
// $info # 目前已订阅的频道数量 或 信息内容
list($type, $name, $info) = $msg;
if ($type == 'subscribe') // 或psubscribe
{
// 频道订阅成功消息,订阅几个频道就有几条
}
else if ($type == 'unsubscribe' && $info == 0) // 或punsubscribe
{
break; // 收到取消订阅消息,并且剩余订阅的频道数为0,不再接收,结束循环
}
else if ($type == 'message') // 若为psubscribe,此处为pmessage
{
// 打印来源频道名字
var_dump($name);
// 打印消息
var_dump($info);
// 处理消息
if ($need_unsubscribe) // 某个情况下需要退订
{
$redis->unsubscribe(); // 继续recv等待退订完成
}
}
}
}