2023-01-11 18:31:20 +00:00
|
|
|
package com.vitorpamplona.amethyst.service.relays
|
|
|
|
|
|
|
|
import androidx.lifecycle.LiveData
|
2023-06-07 16:08:13 +00:00
|
|
|
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
2023-08-16 21:58:25 +00:00
|
|
|
import com.vitorpamplona.quartz.events.Event
|
|
|
|
import com.vitorpamplona.quartz.events.EventInterface
|
2023-01-19 22:52:32 +00:00
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
import kotlinx.coroutines.Job
|
|
|
|
import kotlinx.coroutines.launch
|
2023-01-11 18:31:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* RelayPool manages the connection to multiple Relays and lets consumers deal with simple events.
|
|
|
|
*/
|
2023-03-07 18:46:44 +00:00
|
|
|
object RelayPool : Relay.Listener {
|
2023-02-05 05:41:37 +00:00
|
|
|
|
|
|
|
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
|
|
|
|
2023-01-17 13:42:00 +00:00
|
|
|
private var relays = listOf<Relay>()
|
|
|
|
private var listeners = setOf<Listener>()
|
2023-01-11 18:31:20 +00:00
|
|
|
|
2023-01-14 02:35:28 +00:00
|
|
|
fun availableRelays(): Int {
|
|
|
|
return relays.size
|
|
|
|
}
|
|
|
|
|
|
|
|
fun connectedRelays(): Int {
|
2023-07-23 22:37:37 +00:00
|
|
|
return relays.count { it.isConnected() }
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
2023-01-23 16:58:06 +00:00
|
|
|
fun getRelay(url: String): Relay? {
|
|
|
|
return relays.firstOrNull() { it.url == url }
|
|
|
|
}
|
|
|
|
|
2023-05-17 17:54:20 +00:00
|
|
|
fun getRelays(url: String): List<Relay> {
|
|
|
|
return relays.filter { it.url == url }
|
|
|
|
}
|
|
|
|
|
2023-03-07 18:46:44 +00:00
|
|
|
fun loadRelays(relayList: List<Relay>) {
|
|
|
|
if (!relayList.isNullOrEmpty()) {
|
2023-01-11 18:31:20 +00:00
|
|
|
relayList.forEach { addRelay(it) }
|
|
|
|
} else {
|
2023-02-05 23:14:41 +00:00
|
|
|
Constants.convertDefaultRelays().forEach { addRelay(it) }
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun unloadRelays() {
|
2023-01-17 13:42:00 +00:00
|
|
|
relays.forEach { it.unregister(this) }
|
|
|
|
relays = listOf()
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fun requestAndWatch() {
|
2023-06-07 16:08:13 +00:00
|
|
|
checkNotInMainThread()
|
|
|
|
|
2023-07-25 14:23:20 +00:00
|
|
|
relays.forEach { it.connect() }
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fun sendFilter(subscriptionId: String) {
|
|
|
|
relays.forEach { it.sendFilter(subscriptionId) }
|
|
|
|
}
|
|
|
|
|
2023-01-17 13:42:00 +00:00
|
|
|
fun sendFilterOnlyIfDisconnected() {
|
|
|
|
relays.forEach { it.sendFilterOnlyIfDisconnected() }
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
2023-07-17 12:48:34 +00:00
|
|
|
fun sendToSelectedRelays(list: List<Relay>, signedEvent: EventInterface) {
|
|
|
|
list.forEach { relay ->
|
|
|
|
relays.filter { it.url == relay.url }.forEach { it.send(signedEvent) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-05 21:42:19 +00:00
|
|
|
fun send(signedEvent: EventInterface) {
|
2023-01-11 18:31:20 +00:00
|
|
|
relays.forEach { it.send(signedEvent) }
|
|
|
|
}
|
|
|
|
|
2023-03-07 18:46:44 +00:00
|
|
|
fun close(subscriptionId: String) {
|
2023-01-11 18:31:20 +00:00
|
|
|
relays.forEach { it.close(subscriptionId) }
|
|
|
|
}
|
|
|
|
|
|
|
|
fun disconnect() {
|
|
|
|
relays.forEach { it.disconnect() }
|
|
|
|
}
|
|
|
|
|
|
|
|
fun addRelay(relay: Relay) {
|
|
|
|
relay.register(this)
|
|
|
|
relays += relay
|
|
|
|
}
|
|
|
|
|
2023-01-17 13:42:00 +00:00
|
|
|
fun removeRelay(relay: Relay) {
|
2023-01-11 18:31:20 +00:00
|
|
|
relay.unregister(this)
|
2023-01-17 13:42:00 +00:00
|
|
|
relays = relays.minus(relay)
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fun register(listener: Listener) {
|
2023-01-17 13:42:00 +00:00
|
|
|
listeners = listeners.plus(listener)
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
2023-01-17 13:42:00 +00:00
|
|
|
fun unregister(listener: Listener) {
|
|
|
|
listeners = listeners.minus(listener)
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
interface Listener {
|
|
|
|
fun onEvent(event: Event, subscriptionId: String, relay: Relay)
|
|
|
|
|
|
|
|
fun onError(error: Error, subscriptionId: String, relay: Relay)
|
|
|
|
|
2023-02-02 19:34:34 +00:00
|
|
|
fun onRelayStateChange(type: Relay.Type, relay: Relay, channel: String?)
|
2023-01-14 02:35:28 +00:00
|
|
|
|
|
|
|
fun onSendResponse(eventId: String, success: Boolean, message: String, relay: Relay)
|
2023-04-26 01:18:33 +00:00
|
|
|
|
|
|
|
fun onAuth(relay: Relay, challenge: String)
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onEvent(relay: Relay, subscriptionId: String, event: Event) {
|
|
|
|
listeners.forEach { it.onEvent(event, subscriptionId, relay) }
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onError(relay: Relay, subscriptionId: String, error: Error) {
|
|
|
|
listeners.forEach { it.onError(error, subscriptionId, relay) }
|
|
|
|
refreshObservers()
|
|
|
|
}
|
|
|
|
|
2023-02-02 19:34:34 +00:00
|
|
|
override fun onRelayStateChange(relay: Relay, type: Relay.Type, channel: String?) {
|
|
|
|
listeners.forEach { it.onRelayStateChange(type, relay, channel) }
|
2023-01-11 18:31:20 +00:00
|
|
|
refreshObservers()
|
|
|
|
}
|
|
|
|
|
2023-01-14 02:35:28 +00:00
|
|
|
override fun onSendResponse(relay: Relay, eventId: String, success: Boolean, message: String) {
|
|
|
|
listeners.forEach { it.onSendResponse(eventId, success, message, relay) }
|
|
|
|
}
|
|
|
|
|
2023-04-26 01:18:33 +00:00
|
|
|
override fun onAuth(relay: Relay, challenge: String) {
|
|
|
|
listeners.forEach { it.onAuth(relay, challenge) }
|
|
|
|
}
|
|
|
|
|
2023-01-11 18:31:20 +00:00
|
|
|
// Observers line up here.
|
|
|
|
val live: RelayPoolLiveData = RelayPoolLiveData(this)
|
|
|
|
|
|
|
|
private fun refreshObservers() {
|
2023-01-19 22:52:32 +00:00
|
|
|
scope.launch {
|
|
|
|
live.refresh()
|
|
|
|
}
|
2023-01-11 18:31:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-07 18:46:44 +00:00
|
|
|
class RelayPoolLiveData(val relays: RelayPool) : LiveData<RelayPoolState>(RelayPoolState(relays)) {
|
2023-01-11 18:31:20 +00:00
|
|
|
fun refresh() {
|
|
|
|
postValue(RelayPoolState(relays))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-05 21:42:19 +00:00
|
|
|
class RelayPoolState(val relays: RelayPool)
|