@StartableByRPC
We also mark InitiatorFlow
as StartableByRPC
, allowing the
node’s owner to start the flow via RPC.
如果没有此注解的话,节点对应的api就无法开启此flow。
@InitiatingFlow
InitiatorFlow
is our first flow, and will communicate with
ResponderFlow
, below.
We mark InitiatorFlow
as an InitiatingFlow
, allowing it to be
started directly by the node.
利用flow可以建立节点之间的session,并进行通信,发送数据。但是此flow一定需要被@InitiatingFlow修饰才可以。否则就会报错。
@InitiatedBy(xxxFlow)
此注解是响应另一个flow的。
@Suspendale
此注解是每个flow必须的,不是可选项。必须实现。Corda源码会进行逻辑判断。如果没有的话,就会报错,并告诉你需要添加此注解。
@CordaSerializable
从节点对应的api,它调用node的flow方法,并传入数据,此实体都需要进行CordaSerializable,不然也会报错,并告诉你需要添加才注解。
@StartableByRPC
@InitiatingFlow
AFlow
//并在代码显示建立与哪个节点建立会话,并进行会话。
val session = initiateFlow(party) //这是Kotlin的写法
session.send(data) //当AFlow执行到此语句的时候,会自动触发到AResponserFlow的逻辑,他们相互发送和接收数据
//这是一个响应AFlow发送过来的信息的Flow
@InitiatedBy(AFlow)
AResponserFlow
请问RPC除了调用Corda节点中的Flow,并与Corda节点交互外,还有什么作用呢?
RPC可以像我们平常的Jave web开发的代码一样,里面有处理请求,处理数据的功能逻辑。把整理好的数据,通过Flow传送给Corda节点。
请问Corda节点与我们开发写的cordapp有什么关系呢?
Corda节点其实跟Tomcat很像,他可以接收到请求并能够处理请求。并且启动Corda节点的jar包,可以是任意的,比如你可以去Corda源码中打好一个corda.jar或者就是我们开发环境中生成节点信息的时候,自动生成的corda.jar也是可以的,可以这样理解一处生成codar.jar处处可以使用。
cordapp可以理解为他是运行在Corda平台的逻辑代码。也就是我们开发人员根据现实生活的业务场景,设计的一些概念,类,方法的逻辑代码。
关系就是:Corda节点是服务,是容器,可以处理请求。cordapp是容器中的内容,寄生在Corda节点容器中的,只要内存满足,corda节点可以寄生很多cordapp代码。
请问我理解了cordapp与corda节点关系,那他们是怎么耦合起来的呢
Java程序员都知道Spring。里面有个POJO概念。它是表达我们应用程序写的Java类变成了可以被Spring使用的类,其实就是被注入到Spring了,被注入到Spring了有什么好处呢?就是Spring帮我们管理嘛。然后我使用组合的思想把这些属于Spring的对象组合到我们想要的类中。他非常好。因为Spring是非侵入式编程。这个POJO不影响我们原来对我们定义的Java类的理解。
可是Corda是怎么处理的呢?它有学习Spring这种非侵入式编程吗
答案是否定的。就是开发人员写的cordapp逻辑代码需要实现或者继承Corda源码中的高层接口。这样关系就建立起来了。它是Corda节点启动的时候,会这些我们自己独立写的Schema,State,Contract,Flow等都属于Corda源码中维护好的一个List,这个List中就装满了我们自定义的Schema,State,Contract,Flow等信息。因为cordapp算是Corda平台的一部分,它们本就需要耦合上。但是学习Spring这种思想,又应该如何编写Corda源码呢?
** 源码**
override val contractClassNames: List,
override val initiatedFlows: List<Class<out FlowLogic<>>>,
override val rpcFlows: List<Class<out FlowLogic<>>>,
override val serviceFlows: List<Class<out FlowLogic<>>>,
override val schedulableFlows: List<Class<out FlowLogic<>>>,
override val services: List<Class>,
override val serializationWhitelists: List,
override val serializationCustomSerializers: List<SerializationCustomSerializer<*, *>>,
override val customSchemas: Set,
请问可是节点与节点又是怎么进行交互的呢?
当Corda源码"看见"某个Flow被此注解了。那就说明此节点下的此Flow拥有了一个能力就是与别的节点下的Flow进行交互。此Flow代码逻辑下面,找到与哪个节点进行交互的节点信息,然后建立Session。通过send方式进行发送数据。
请问这个过程是怎样交互的呢?
A节点必须明确在整个网络上与谁建立Session。然后通过send的方法发送数据。一旦代码执行到send方法的时候。接收者的节点自动触发flow。可是否receive方法接收数据。这个时候接收者可以执行自己的代码逻辑,比如连接数据库查询数据信息,写业务逻辑代码等操作。
请问这个过程一直阻塞吗?
是的。发起者一直等待接收者响应信息。
请问调用Flow都是阻塞的方法吗?
是的。这个时候,请求一直等待响应。直到响应接收。如果在这个过程中,交互的某个节点宕机了,就会一直阻塞。
请问上一个交易一直阻塞,会影响我后面建立的交易吗
不会。你仍然可以继续建立交易。这些交易都是通过状态机记录的。保证了在并发下也是安全的。而且即使在交易过程中宕机,后面重启节点,交易记录依然可以持久化到数据中。