关于coroutine:Android中的Coroutine协程原理详解

前言协程是一个并发计划。也是一种思维。 传统意义上的协程是单线程的,面对io密集型工作他的内存耗费更少,进而效率高。然而面对计算密集型的工作不如多线程并行运算效率高。 不同的语言对于协程都有不同的实现,甚至同一种语言对于不同平台的操作系统都有对应的实现。 咱们kotlin语言的协程是 coroutines for jvm的实现形式。底层原理也是利用java 线程。 基础知识生态架构 相干依赖库dependencies { // Kotlin implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.32" // 协程外围库 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3" // 协程Android反对库 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3" // 协程Java8反对库 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.4.3" // lifecycle对于协程的扩大封装 implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0" implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"}为什么一些人总感觉协程艰涩难懂?1.网络上没有具体的对于协程的概念定义,每种语言、每个系统对其实现都不一样。堪称是七嘴八舌,什么内核态用户态巴拉巴拉,很容易给咱们带偏 2.kotlin的各种语法糖对咱们造成的烦扰。如: 高阶函数源码实现类找不到所以扎实的kotlin语法基本功是学习协程的前提。 切实看不懂得中央就反编译为java,以java最终翻译为准。 协程是什么?有什么用?kotlin中的协程干的事就是把异步回调代码拍扁了,捋直了,让异步回调代码同步化。除此之外,没有任何特别之处。 创立一个协程,就是编译器背地偷偷生成一系列代码,比如说状态机。 通过挂起和复原让状态机状态流转实现把层层嵌套的回调代码变成像同步代码那样直观、简洁。 它不是什么线程框架,也不是什么浅近的内核态,用户态。它其实对于咱们安卓来说,就是一个对于回调函数的语法糖。。。 本文将会围绕挂起与复原彻底分析协程的实现原理 Kotlin函数基础知识温习再Kotlin中函数是一等公民,有本人的类型 函数类型fun foo(){}//类型为 () -> Unitfun foo(p: Int){}//类型为 (Int) -> Stringclass Foo{ fun bar(p0: String,p1: Long):Any{} }//那么 bar 的类型为:Foo.(String,Long) -> Any//Foo就是bar的 receiver。也能够写成 (Foo,String,Long) ->Any函数援用fun foo(){} //援用是 ::foofun foo(p0: Int): String//援用也是 ::foo咋都一样?没方法,就这样规定的。应用的时候 只能靠编译器推断 ...

March 29, 2022 · 5 min · jiezi

????-Hyperf-多个组件-v104-更新-企业级的-PHP-微服务协程框架

v1.0.4 更新内容本次更新涉及以下组件,主要增加了 Swoole 4.4 的支持及部分组件的功能强化,以及修复了一些 Bug hyperf/async-queue hyperf/command hyperf/config hyperf/constants hyperf/consul hyperf/contract hyperf/database hyperf/db-connection hyperf/di hyperf/dispatcher hyperf/framework hyperf/http-server hyperf/pool hyperf/redis hyperf/rpc-client hyperf/service-governance hyperf/utils hyperf/websocket-server 新增#140 支持 Swoole v4.4.0.#152 数据库连接在低使用率时连接池会自动释放连接#163 constants 组件的AbstractConstants::__callStatic 支持自定义参数变更#124 DriverInterface::push 增加 $delay 参数用于设置延迟时间, 同时 DriverInterface::delay 将标记为弃用的,将于 1.1 版本移除#125 更改 config() 函数的 $default 参数的默认值为 null.修复#110 #111 修复 Redis::select 无法正常切换数据库的问题#131 修复 middlewares 配置在 Router::addGroup 下无法正常设置的问题#132 修复 request->hasFile 判断条件错误的问题#135 修复 response->redirect 在调整外链时无法正确生成链接的问题#139 修复 ConsulAgent 的 URI 无法自定义设置的问题#148 修复当 migrates 文件夹不存在时无法生成迁移模板的问题#169 修复处理请求时没法正确处理数组类型的参数#170 修复当路由不存在时 WebSocket Server 无法正确捕获异常的问题移除#131 移除 Router options 里的 server 参数关于 HyperfHyperf 是基于 Swoole 4.3+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换 与 可复用 的。   框架组件库除了常见的协程版的 MySQL 客户端、Redis 客户端,还为您准备了协程版的 Eloquent ORM、JSON RPC 服务的及客户端、GRPC 服务端及客户端、Zipkin (OpenTracing) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul 客户端、ETCD 客户端、AMQP 组件、Apollo 配置中心、阿里云 ACM 应用配置管理、基于令牌桶算法的限流器、通用连接池、熔断器、Swagger 文档生成 等组件,省去了自己实现对应协程版本的麻烦,Hyperf 还提供了 基于 PSR-11 的依赖注入容器、注解、AOP 面向切面编程、基于 PSR-15 的中间件、自定义进程、基于 PSR-14 的事件管理器、Redis/RabbitMQ 消息队列、自动模型缓存、基于 PSR-16 的缓存 等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。 ...

July 9, 2019 · 1 min · jiezi

????-Hyperf-发布-WebSocket-组件-及-多个组件-v103-更新-企业级的-PHP-微服务协程框架

v1.0.3 更新内容本次更新涉及以下组件,主要新增了 WebSocket 服务端 及 WebSocket 协程客户端 组件,以及修复了一些 Bug hyperf/constantshyperf/databasehyperf/dihyperf/frameworkhyperf/http-serverhyperf/json-rpchyperf/model-cachehyperf/websocket-clienthyperf/websocket-server Added#48 增加 WebSocket 协程客户端及服务端#51 增加了 enableCache 参数去控制 DefinitionSource 是否启用注解扫描缓存#61 通过 db:model 命令创建模型时增加属性类型#65 模型缓存增加 JSON 格式支持Changed#46 移除了 hyperf/di, hyperf/command and hyperf/dispatcher 组件对 hyperf/framework 组件的依赖Fixed#45 修复当引用了 hyperf/websocket-server 组件时有可能会导致 HTTP Server 启动失败的问题#55 修复方法级别的 @Middleware 注解可能会被覆盖的问题#73 修复 db:model 命令对短属性处理不正确的问题#88 修复当控制器存在多层文件夹时生成的路由可能不正确的问题#101 修复常量不存在 @Message 注解时会报错的问题WebSocket 服务Hyperf 提供了对 WebSocket Server 的封装,可基于 hyperf/websocket-server 组件快速搭建一个 WebSocket 应用。 安装composer require hyperf/websocket-server配置 Server修改 config/autoload/server.php,增加以下配置。 <?php'servers' => [ [ 'name' => 'ws', 'type' => Server::SERVER_WEBSOCKET, 'host' => '0.0.0.0', 'port' => 9502, 'sock_type' => SWOOLE_SOCK_TCP, 'callbacks' => [ SwooleEvent::ON_HAND_SHAKE => [Hyperf\WebSocketServer\Server::class, 'onHandShake'], SwooleEvent::ON_MESSAGE => [Hyperf\WebSocketServer\Server::class, 'onMessage'], SwooleEvent::ON_CLOSE => [Hyperf\WebSocketServer\Server::class, 'onClose'], ], ],],配置路由目前暂时只支持配置文件的模式配置路由,后续会提供注解模式。在 config/routes.php 文件内增加对应 ws 的 Server 的路由配置,这里的 ws 值取决于您在 config/autoload/server.php 内配置的 WebSocket Server 的 name 值。 ...

July 2, 2019 · 2 min · jiezi

What-你还不知道Kotlin-Coroutine

今天我们来聊聊Kotlin Coroutine,如果你还没有了解过,那么我要提前恭喜你,因为你将掌握一个新技能,对你的代码方面的提升将是很好的助力。 What Coroutine简单的来说,Coroutine是一个并发的设计模式,你能通过它使用更简洁的代码来解决异步问题。 例如,在Android方面它主要能够帮助你解决以下两个问题: 在主线程中执行耗时任务导致的主线程阻塞,从而使App发生ANR。提供主线程安全,同时对来自于主线程的网络回调、磁盘操提供保障。这些问题,在接下来的文章中我都会给出解决的示例。 Callback说到异步问题,我们先来看下我们常规的异步处理方式。首先第一种是最基本的callback方式。 callback的好处是使用起来简单,但你在使用的过程中可能会遇到如下情形 GatheringVoiceSettingRepository.getInstance().getGeneralSettings(RequestLanguage::class.java) .observe(this, { language -> convertResult(language, { enable -> // todo something }) })这种在其中一个callback中回调另一个callback回调,甚至更多的callback都是可能存在。这些情况导致的问题是代码间的嵌套层级太深,导致逻辑嵌套复杂,后续的维护成本也要提高,这不是我们所要看到的。 那么有什么方法能够解决呢?当然有,其中的一种解决方法就是我接下来要说的第二种方式。 Rx系列对多嵌套回调,Rx系列在这方面处理的已经非常好了,例如RxJava。下面我们来看一下RxJava的解决案例 disposable = createCall().map { // return RequestType }.subscribeWith(object : SMDefaultDisposableObserver<RequestType>{ override fun onNext(t: RequestType) { // todo something } })RxJava丰富的操作符,再结合Observable与Subscribe能够很好的解决异步嵌套回调问题。但是它的使用成本就相对提高了,你要对它的操作符要非常了解,避免在使用过程中滥用或者过度使用,这样自然复杂度就提升了。 那么我们渴望的解决方案是能够更加简单、全面与健壮,而我们今天的主题Coroutine就能够达到这种效果。 Coroutine在Kotlin中的基本要点在Android里,我们都知道网络请求应该放到子线程中,相应的回调处理一般都是在主线程,即ui线程。正常的写法就不多说了,那么使用Coroutine又该是怎么样的呢?请看下面代码示例: private suspend fun get(url: String) = withContext(Dispatchers.IO) { // to do network request url } private suspend fun fetch() { // 在Main中调用 val result = get("https://rousetime.com") // 在IO中调用 showToast(result) // 在Main中调用 }如果fetch方法在主线程调用,那么你会发现使用Coroutine来处理异步回调就像是在处理同步回调一样,简洁明了、行云流水,同时再也没有嵌套的逻辑了。 ...

June 28, 2019 · 2 min · jiezi

????-Hyperf-骨架-v103-及多个组件-v101-更新-企业级的-PHP-微服务协程框架

更新内容hyperf-skeleton v1.0.3Added安装器为 RPC 部分增加 JSON RPC with Service Governance 选项, 选择该选项会自动安装 hyperfservice-governance 组件;骨架内提供的 App\Exception\Handler\AppExcpetionHandler 默认输出异常信息Changed将 App\Model\Model 修改为一个抽象类Fixed修复 open(runtime/hyperf.pid) failed, Error: No such file or directory 的错误;修复 format_throwable() 函数未被定义的错误;database v1.0.1Fixed修复 DB::raw() 无法支持强制索引的问题;http-server v1.0.1Fixed定义路由时的路由方法不再区分大小写testing v1.0.1Fixed修复 flushContext 方法没有按预期运行的问题关于 HyperfHyperf 是基于 Swoole 4.3+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换 与 可复用 的。   框架组件库除了常见的协程版的 MySQL 客户端、Redis 客户端,还为您准备了协程版的 Eloquent ORM、JSON RPC 服务的及客户端、GRPC 服务端及客户端、Zipkin (OpenTracing) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul 客户端、ETCD 客户端、AMQP 组件、Apollo 配置中心、阿里云 ACM 应用配置管理、基于令牌桶算法的限流器、通用连接池、熔断器、Swagger 文档生成 等组件,省去了自己实现对应协程版本的麻烦,Hyperf 还提供了 基于 PSR-11 的依赖注入容器、注解、AOP 面向切面编程、基于 PSR-15 的中间件、自定义进程、基于 PSR-14 的事件管理器、Redis/RabbitMQ 消息队列、自动模型缓存、基于 PSR-16 的缓存 等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。 ...

June 24, 2019 · 1 min · jiezi

????-Hyperf-v10-发布全新企业级的-PHP-协程框架

HyperfHyperf 是基于 Swoole 4.3+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换 与 可复用 的。 框架组件库除了常见的协程版的 MySQL 客户端、Redis 客户端,还为您准备了协程版的 Eloquent ORM、JSON RPC 服务的及客户端、GRPC 服务端及客户端、Zipkin (OpenTracing) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul 客户端、ETCD 客户端、AMQP 组件、Apollo 配置中心、阿里云 ACM 应用配置管理、基于令牌桶算法的限流器、通用连接池、熔断器、Swagger 文档生成 等组件,省去了自己实现对应协程版本的麻烦,Hyperf 还提供了 基于 PSR-11 的依赖注入容器、注解、AOP 面向切面编程、基于 PSR-15 的中间件、自定义进程、基于 PSR-14 的事件管理器、Redis/RabbitMQ 消息队列、自动模型缓存、基于 PSR-16 的缓存 等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。 框架初衷尽管现在基于 PHP 语言开发的框架处于一个百花争鸣的时代,但仍旧未能看到一个优雅的设计与超高性能的共存的完美框架,亦没有看到一个真正为 PHP 微服务铺路的框架,此为 Hyperf 及其团队成员的初衷,我们将持续投入并为此付出努力,也欢迎你加入我们参与开源建设。 设计理念Hyperspeed + Flexibility = Hyperf,从名字上我们就将 超高速 和 灵活性 作为 Hyperf 的基因。 ...

June 20, 2019 · 1 min · jiezi

tornado 源码之 coroutine 分析

tornado 源码之 coroutine 分析tornado 的协程原理分析 版本:4.3.0为支持异步,tornado 实现了一个协程库。tornado 实现的协程框架有下面几个特点:支持 python 2.7,没有使用 yield from特性,纯粹使用 yield 实现使用抛出异常的方式从协程返回值采用 Future 类代理协程(保存协程的执行结果,当携程执行结束时,调用注册的回调函数)使用 IOLoop 事件循环,当事件发生时在循环中调用注册的回调,驱动协程向前执行由此可见,这是 python 协程的一个经典的实现。本文将实现一个类似 tornado 实现的基础协程框架,并阐述相应的原理。外部库使用 time 来实现定时器回调的时间计算。 bisect 的 insort 方法维护一个时间有限的定时器队列。 functools 的 partial 方法绑定函数部分参数。 使用 backports_abc 导入 Generator 来判断函数是否是生成器。import timeimport bisectimport functoolsfrom backports_abc import Generator as GeneratorTypeFuture是一个穿梭于协程和调度器之间的信使。 提供了回调函数注册(当异步事件完成后,调用注册的回调)、中间结果保存、结束结果返回等功能add_done_callback 注册回调函数,当 Future 被解决时,改回调函数被调用。 set_result 设置最终的状态,并且调用已注册的回调函数协程中的每一个 yield 对应一个协程,相应的对应一个 Future 对象,譬如:@coroutinedef routine_main(): yield routine_simple() yield sleep(1)这里的 routine_simple() 和 sleep(1) 分别对应一个协程,同时有一个 Future 对应。class Future(object): def init(self): self._done = False self._callbacks = [] self._result = None def _set_done(self): self._done = True for cb in self._callbacks: cb(self) self._callbacks = None def done(self): return self._done def add_done_callback(self, fn): if self._done: fn(self) else: self._callbacks.append(fn) def set_result(self, result): self._result = result self._set_done() def result(self): return self._resultIOLoop这里的 IOLoop 去掉了 tornado 源代码中 IO 相关部分,只保留了基本需要的功能,如果命名为 CoroutineLoop 更贴切。这里的 IOLoop 提供基本的回调功能。它是一个线程循环,在循环中完成两件事:检测有没有注册的回调并执行检测有没有到期的定时器回调并执行程序中注册的回调事件,最终都会在此处执行。可以认为,协程程序本身、协程的驱动程序 都会在此处执行。协程本身使用 wrapper 包装,并最后注册到 IOLoop 的事件回调,所以它的从预激到结束的代码全部在 IOLoop 回调中执行。而协程预激后,会把 Runner.run() 函数注册到 IOLoop 的事件回调,以驱动协程向前运行。理解这一点对于理解协程的运行原理至关重要。这就是单线程异步的基本原理。因为都在一个线程循环中执行,我们可以不用处理多线程需要面对的各种繁琐的事情。coroutine协程返回值sleepRunner因为没有使用 yield from,协程无法直接返回值,所以使用抛出异常的方式返回。copyrightauthor:bigfish copyright: 许可协议 知识共享署名-非商业性使用 4.0 国际许可协议 ...

January 16, 2019 · 1 min · jiezi

PHP下的异步尝试二:初识协程

PHP下的异步尝试系列如果你还不太了解PHP下的生成器,你可以根据下面目录翻阅PHP下的异步尝试一:初识生成器PHP下的异步尝试二:初识协程PHP下的异步尝试三:协程的Co自动执行器 [待开发]PHP下的异步尝试四:PHP版的Promise [待开发]…多任务 (并行和并发)在讲协程之前,先谈谈多进程、多线程、并行和并发。对于单核处理器,多进程实现多任务的原理是让操作系统给一个任务每次分配一定的 CPU 时间片,然后中断、让下一个任务执行一定的时间片接着再中断并继续执行下一个,如此反复。由于切换执行任务的速度非常快,给外部用户的感受就是多个任务的执行是同时进行的。多进程的调度是由操作系统来实现的,进程自身不能控制自己何时被调度,也就是说: 进程的调度是由外层调度器抢占式实现的而协程要求当前正在运行的任务自动把控制权回传给调度器,这样就可以继续运行其他任务。这与抢占式的多任务正好相反, 抢占多任务的调度器可以强制中断正在运行的任务, 不管它自己有没有意愿。如果仅依靠程序自动交出控制的话,那么一些恶意程序将会很容易占用全部 CPU 时间而不与其他任务共享。协程的调度是由协程自身主动让出控制权到外层调度器实现的回到刚才生成器实现 xrange 函数的例子,整个执行过程的交替可以用下图来表示:协程可以理解为纯用户态的线程,通过协作而不是抢占来进行任务切换。相对于进程或者线程,协程所有的操作都可以在用户态而非操作系统内核态完成,创建和切换的消耗非常低。简单的说协程 就是提供一种方法来中断当前任务的执行,保存当前的局部变量,下次再过来又可以恢复当前局部变量继续执行。我们可以把大任务拆分成多个小任务轮流执行,如果有某个小任务在等待系统 IO,就跳过它,执行下一个小任务,这样往复调度,实现了 IO 操作和 CPU 计算的并行执行,总体上就提升了任务的执行效率,这也便是协程的意义多线程在单核下,多线程必定是并发的;不过现在的统一进程的多线程是可以运行在多核CPU下,所以可以是并行的并发(Concurrency)是指能处理多个同时性活动的能力,并发事件之间不一定要同一时刻发生。并行(Parallesim)是指同时发生的两个并发事件,具有并发的含义,而并发则不一定并行。多个操作可以在重叠的时间段内进行。并行和并发区别并发指的是程序的结构,并行指的是程序运行时的状态并行一定是并发的,并行是并发设计的一种单线程永远无法达到并行状态协程协程的支持是在生成器的基础上, 增加了可以回送数据给生成器的功能(调用者发送数据给被调用的生成器函数). 这就把生成器到调用者的单向通信转变为两者之间的双向通信.我们在上篇文章已经讲过了send方法, 下面让我们理解下协程同步代码在没有涉及到异步执行代码之前,我们的代码都是这样的function printNum($max, $caller){ for ($i=0; $i<$max; $i++ ) { echo “调度者:” . $caller . " 打印:" . $i . PHP_EOL; }}printNum(3, “caller1”);printNum(3, “caller2”);# output调度者:caller1 打印:0调度者:caller1 打印:1调度者:caller1 打印:2调度者:caller2 打印:0调度者:caller2 打印:1调度者:caller2 打印:2使用协程后改进的代码初稿,手动调整生成器执行# 本代码手动调整了进程执行代码的顺序,当然本代码实现不用协程也可以,只是利用本流程说明协程作用# 生成器给了我们函数中断,协程[生成器send]给了我们重新唤起生成器函数的能力function printNumWithGen($max){ for ($i=0; $i<$max; $i++ ) { $res = yield $i; echo $res; }}$gen1 = printNumWithGen(3);$gen2 = printNumWithGen(3);// 手动执行caller1 再 caller2$gen1->send(“调度者: caller1 打印:” . $gen1->current() . PHP_EOL);$gen2->send(“调度者: caller2 打印:” . $gen2->current() . PHP_EOL);// 手动执行caller1 再 caller2$gen1->send(“调度者: caller1 打印:” . $gen1->current() . PHP_EOL);$gen2->send(“调度者: caller2 打印:” . $gen2->current() . PHP_EOL);// 手动执行caller2 再 caller1$gen2->send(“调度者: caller2 打印:” . $gen2->current() . PHP_EOL);$gen1->send(“调度者: caller1 打印:” . $gen1->current() . PHP_EOL);# output调度者: caller1 打印:0调度者: caller2 打印:0调度者: caller1 打印:1调度者: caller2 打印:1调度者: caller2 打印:2调度者: caller1 打印:2总结上面案例应该让大家理解了协程设计的意义和如何使用协程那么接下去我们为我们的协程自动一个自动调度器(Co自动执行器),无需再手动来中断和恢复了 ...

September 20, 2018 · 1 min · jiezi

Swoole 4.1.0 正式版发布,支持原生 Redis/PDO/MySQLi 协程化

重大新特性支持 Redis/PDO/MySQLi从4.1.0版本开始支持了对PHP原生Redis、PDO、MySQLi协程化的支持。可使用SwooleRuntime::enableCorotuine()将普通的同步阻塞Redis、PDO、MySQLi操作变为协程调度的异步非阻塞IOSwooleRuntime::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)可获取某个协程的函数调用栈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); }});BackTrace[1]:———————————————–#0 SwooleCoroutine::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]其他修改重构 CoChannel C底层代码为C++, 解决复杂场景的非预期结果, 实现高稳定重构 CoHttpClient C底层代码为C++协程模式, 解决异步时序问题, 实现高稳定支持在协程和Server中使用exit, 此时将会抛出可捕获的SwooleExitException异常移除所有迭代器(table/connection/coroutine_list)的PCRE依赖限制增加open_websocket_close_frame配置, 可以在onMessage事件中接收close帧废弃HttpResponse->gzip()方法,改为使用http_compression配置项。底层会自动判断客户端传入的Accept-Encoding选择合适的压缩方法, 新增谷歌BR压缩支持增加CoHttpClient->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版本下的所有级别的编译warningGCC版本小于4.8时将会产生编译错误修复MySQL使用prepare时未使用参数绑定导致的内存分配不断增长修复HTTP2重连时旧stream内存丢失泄露底层开发相关统一文件命名 #970CoHttpClient使用了create_obj和free_obj保证内存安全, 防止错误的PHP代码引发内存问题 ...

September 1, 2018 · 1 min · jiezi