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配置指定OnOff时能正确显示(而不是显示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多次waitwakeup溢出的问题 (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等待退订完成
            }
        }
    }
}