Implement two way communication with Dero node.
- Implemented basic two way communication with the Dero node. The Bridge is listening for Dero node updates and requests the Block Height when receiving a Height update from the node. - Renamed Bridge to StargateBridge and added basic documentation. - Created model for DeroNode instances. We use only one node for now, but will add more down the line.
This commit is contained in:
parent
8b9727082a
commit
8189b590d3
4 changed files with 75 additions and 37 deletions
|
@ -5,19 +5,19 @@ import cafe.adriel.voyager.core.model.screenModelScope
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.launch
|
||||
import net.agorise.shared.stargate.Bridge
|
||||
import net.agorise.shared.stargate.StargateBridge
|
||||
|
||||
class ImportAccountScreenModel : ScreenModel {
|
||||
private val bridge = Bridge()
|
||||
private val stargateBridge = StargateBridge()
|
||||
|
||||
init {
|
||||
screenModelScope.launch(Dispatchers.IO) {
|
||||
bridge.start()
|
||||
stargateBridge.start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDispose() {
|
||||
super.onDispose()
|
||||
bridge.stop()
|
||||
stargateBridge.stop()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package net.agorise.shared.stargate
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.plugins.websocket.DefaultClientWebSocketSession
|
||||
import io.ktor.client.plugins.websocket.WebSockets
|
||||
import io.ktor.client.plugins.websocket.webSocket
|
||||
import io.ktor.http.HttpMethod
|
||||
import io.ktor.websocket.Frame
|
||||
import io.ktor.websocket.readText
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
|
||||
class Bridge {
|
||||
private val client: HttpClient = HttpClient(CIO) { install(WebSockets) }
|
||||
|
||||
suspend fun start() {
|
||||
client.webSocket(method = HttpMethod.Get, host = "node.derofoundation.org", port = 11012, path = "/ws") {
|
||||
outputMessages()
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
client.close()
|
||||
}
|
||||
|
||||
private suspend fun DefaultClientWebSocketSession.outputMessages() {
|
||||
incoming.receiveAsFlow().collect { message ->
|
||||
(message as? Frame.Text)?.let { textFrame ->
|
||||
println(textFrame.readText())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package net.agorise.shared.stargate
|
||||
|
||||
/**
|
||||
* Represents a Dero node
|
||||
*
|
||||
* @param host The host or base url of the node
|
||||
* @param port The port of the node
|
||||
* @param path The path of the node
|
||||
*/
|
||||
data class DeroNode(
|
||||
val host: String,
|
||||
val port: Int,
|
||||
val path: String,
|
||||
)
|
|
@ -0,0 +1,57 @@
|
|||
package net.agorise.shared.stargate
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.plugins.websocket.DefaultClientWebSocketSession
|
||||
import io.ktor.client.plugins.websocket.WebSockets
|
||||
import io.ktor.client.plugins.websocket.webSocket
|
||||
import io.ktor.websocket.Frame
|
||||
import io.ktor.websocket.readText
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
|
||||
/**
|
||||
* Bridge to communicate with the DERO Stargate RPC API: https://docs.dero.io/developer/RPC.html
|
||||
*/
|
||||
class StargateBridge {
|
||||
private val foundationNode = DeroNode(host = "node.derofoundation.org", port = 11012, path = "/ws")
|
||||
|
||||
private val client: HttpClient = HttpClient(CIO) { install(WebSockets) }
|
||||
|
||||
private val rendezvousChannel = Channel<Boolean>()
|
||||
|
||||
private val blockCountRequest = "{ \"jsonrpc\": \"2.0\", \"id\": \"1\", \"method\": \"DERO.GetBlockCount\" }"
|
||||
|
||||
suspend fun start() {
|
||||
val node = foundationNode
|
||||
client.webSocket(host = node.host, port = node.port, path = node.path) {
|
||||
writeMessages()
|
||||
readMessages()
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
client.close()
|
||||
}
|
||||
|
||||
private suspend fun DefaultClientWebSocketSession.readMessages() {
|
||||
incoming.receiveAsFlow().collect { message ->
|
||||
(message as? Frame.Text)?.let { textFrame ->
|
||||
val text = textFrame.readText()
|
||||
println(text)
|
||||
if (text.contains("\"method\":\"Block\"")) {
|
||||
rendezvousChannel.send(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun DefaultClientWebSocketSession.writeMessages() {
|
||||
rendezvousChannel.receiveAsFlow().onEach {
|
||||
println("Prepared to send...")
|
||||
outgoing.send(Frame.Text(blockCountRequest))
|
||||
}.launchIn(this)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue