从流进行异步 HTTP 调用
Making asynchronous HTTP calls from flows
在 Corda 中,如何从流中发出异步 HTTP 请求?是否有 API 在等待对 HTTP 调用的响应时暂停流程,或提供回调的方法?
Corda 当前不提供一种机制来发出异步 HTTP 请求,然后在等待响应时暂停流程,或者提供将在收到响应时调用的回调。
相反,建议您在启动流之前发出 HTTP 请求,然后在实例化流时将响应作为参数传递。
有时,这是不可能的。例如,HTTP 请求可能是自动启动的响应流所需要的,或者它可能取决于从交易对方收到的消息的内容。
在这种情况下,您仍然可以支持这种工作流程,如下所示。假设你正在为贷款申请编写一个 CorDapp,表示为 LoanApplicationState
s。没有 HTTP 调用,响应者不知道是否接受贷款申请。
流程不会直接创建 LoanApplicationState
,而是会创建一个 UnacceptedLoanApplicationState
,响应者会将其存储在他们的分类帐中。流程结束后,响应者可以在流程框架之外进行 HTTP 调用。根据 HTTP 调用的结果,响应者将启动批准流程以创建交易以将 UnacceptedLoanApplicationState
转换为 LoanApplicationState
,或者启动拒绝流程以使用 UnacceptedLoanApplicationState
状态没有发出接受 LoanApplicationState
.
或者,您可以向 LoanApplicationState
添加状态字段,指定贷款是否已获批准。最初,贷款状态会将字段设置为未批准。然后,根据 HTTP 请求的结果,响应者将启动两个流程之一来更新 LoanApplicationState
,将其更新为批准或拒绝状态。
Corda 使用 quasar fibers
进行类似同步(异步)的调用。幸好 quasar 支持 java's Future
和 guava's ListenableFuture
.
在此基础上,您可以创建这样的流程
@InitiatingFlow
class ListenableFutureFlow<V>(val futureFn: () -> ListenableFuture<V>,
override val progressTracker: ProgressTracker) : FlowLogic<V>() {
constructor(futureFn: () -> ListenableFuture<V>) : this(futureFn, tracker())
companion object {
object EXECUTING_FUTURE: ProgressTracker.Step("Executing future call inside fiber")
fun tracker() = ProgressTracker(EXECUTING_FUTURE)
}
@Suspendable
override fun call(): V {
progressTracker.currentStep = EXECUTING_FUTURE
return AsyncListenableFuture.get(futureFn())
}
}
你可以这样使用它:
val asyncResponse = subFlow(ListenableFutureFlow { myAsyncCall(param1, param2) })
这不是最好的解决方案,但至少适用于 corda 的基础设施:)
让我知道它是否适合你!
在 Corda 中,如何从流中发出异步 HTTP 请求?是否有 API 在等待对 HTTP 调用的响应时暂停流程,或提供回调的方法?
Corda 当前不提供一种机制来发出异步 HTTP 请求,然后在等待响应时暂停流程,或者提供将在收到响应时调用的回调。
相反,建议您在启动流之前发出 HTTP 请求,然后在实例化流时将响应作为参数传递。
有时,这是不可能的。例如,HTTP 请求可能是自动启动的响应流所需要的,或者它可能取决于从交易对方收到的消息的内容。
在这种情况下,您仍然可以支持这种工作流程,如下所示。假设你正在为贷款申请编写一个 CorDapp,表示为 LoanApplicationState
s。没有 HTTP 调用,响应者不知道是否接受贷款申请。
流程不会直接创建 LoanApplicationState
,而是会创建一个 UnacceptedLoanApplicationState
,响应者会将其存储在他们的分类帐中。流程结束后,响应者可以在流程框架之外进行 HTTP 调用。根据 HTTP 调用的结果,响应者将启动批准流程以创建交易以将 UnacceptedLoanApplicationState
转换为 LoanApplicationState
,或者启动拒绝流程以使用 UnacceptedLoanApplicationState
状态没有发出接受 LoanApplicationState
.
或者,您可以向 LoanApplicationState
添加状态字段,指定贷款是否已获批准。最初,贷款状态会将字段设置为未批准。然后,根据 HTTP 请求的结果,响应者将启动两个流程之一来更新 LoanApplicationState
,将其更新为批准或拒绝状态。
Corda 使用 quasar fibers
进行类似同步(异步)的调用。幸好 quasar 支持 java's Future
和 guava's ListenableFuture
.
在此基础上,您可以创建这样的流程
@InitiatingFlow
class ListenableFutureFlow<V>(val futureFn: () -> ListenableFuture<V>,
override val progressTracker: ProgressTracker) : FlowLogic<V>() {
constructor(futureFn: () -> ListenableFuture<V>) : this(futureFn, tracker())
companion object {
object EXECUTING_FUTURE: ProgressTracker.Step("Executing future call inside fiber")
fun tracker() = ProgressTracker(EXECUTING_FUTURE)
}
@Suspendable
override fun call(): V {
progressTracker.currentStep = EXECUTING_FUTURE
return AsyncListenableFuture.get(futureFn())
}
}
你可以这样使用它:
val asyncResponse = subFlow(ListenableFutureFlow { myAsyncCall(param1, param2) })
这不是最好的解决方案,但至少适用于 corda 的基础设施:)
让我知道它是否适合你!