Merge pull request #986 from greenart7c3/main
Add sendAndWaitForResponse to Client.kt
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
# preserve the line number information for debugging stack traces.
|
||||||
|
-dontobfuscate
|
||||||
|
-keepattributes LocalVariableTable
|
||||||
|
-keepattributes LocalVariableTypeTable
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keepattributes SourceFile
|
||||||
|
-keepattributes LineNumberTable
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes Exceptions
|
||||||
|
-keepattributes InnerClasses
|
||||||
|
-keepattributes EnclosingMethod
|
||||||
|
-keepattributes MethodParameters
|
||||||
|
-keepparameternames
|
||||||
|
|
||||||
|
-keepdirectories libs
|
||||||
|
|
||||||
|
# Keep all names
|
||||||
|
-keepnames class ** { *; }
|
||||||
|
|
||||||
|
# Keep All enums
|
||||||
|
-keep enum ** { *; }
|
||||||
|
|
||||||
|
-keep class com.vitorpamplona.ammolite.service.** { *; }
|
||||||
|
-keep class com.vitorpamplona.ammolite.relays.** { *; }
|
||||||
Vendored
+21
@@ -19,6 +19,27 @@
|
|||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
# preserve the line number information for debugging stack traces.
|
||||||
|
-dontobfuscate
|
||||||
|
-keepattributes LocalVariableTable
|
||||||
|
-keepattributes LocalVariableTypeTable
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keepattributes SourceFile
|
||||||
|
-keepattributes LineNumberTable
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes Exceptions
|
||||||
|
-keepattributes InnerClasses
|
||||||
|
-keepattributes EnclosingMethod
|
||||||
|
-keepattributes MethodParameters
|
||||||
|
-keepparameternames
|
||||||
|
|
||||||
|
-keepdirectories libs
|
||||||
|
|
||||||
|
# Keep all names
|
||||||
|
-keepnames class ** { *; }
|
||||||
|
|
||||||
|
# Keep All enums
|
||||||
|
-keep enum ** { *; }
|
||||||
|
|
||||||
-keep class com.vitorpamplona.ammolite.service.** { *; }
|
-keep class com.vitorpamplona.ammolite.service.** { *; }
|
||||||
-keep class com.vitorpamplona.ammolite.relays.** { *; }
|
-keep class com.vitorpamplona.ammolite.relays.** { *; }
|
||||||
@@ -28,7 +28,10 @@ import kotlinx.coroutines.DelicateCoroutinesApi
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Nostr Client manages multiple personae the user may switch between. Events are received and
|
* The Nostr Client manages multiple personae the user may switch between. Events are received and
|
||||||
@@ -110,7 +113,7 @@ object Client : RelayPool.Listener {
|
|||||||
checkNotInMainThread()
|
checkNotInMainThread()
|
||||||
|
|
||||||
subscribe(
|
subscribe(
|
||||||
object : Listener() {
|
object : Listener {
|
||||||
override fun onEvent(
|
override fun onEvent(
|
||||||
event: Event,
|
event: Event,
|
||||||
subId: String,
|
subId: String,
|
||||||
@@ -130,6 +133,87 @@ object Client : RelayPool.Listener {
|
|||||||
RelayPool.sendFilter(subscriptionId, filters)
|
RelayPool.sendFilter(subscriptionId, filters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
suspend fun sendAndWaitForResponse(
|
||||||
|
signedEvent: EventInterface,
|
||||||
|
relay: String? = null,
|
||||||
|
feedTypes: Set<FeedType>? = null,
|
||||||
|
relayList: List<RelaySetupInfo>? = null,
|
||||||
|
onDone: (() -> Unit)? = null,
|
||||||
|
additionalListener: Listener? = null,
|
||||||
|
timeoutInSeconds: Long = 15,
|
||||||
|
): Boolean {
|
||||||
|
checkNotInMainThread()
|
||||||
|
|
||||||
|
val size = if (relay != null) 1 else relayList?.size ?: RelayPool.availableRelays()
|
||||||
|
val latch = CountDownLatch(size)
|
||||||
|
val relayErrors = mutableMapOf<String, String>()
|
||||||
|
var result = false
|
||||||
|
|
||||||
|
Log.d("sendAndWaitForResponse", "Waiting for $size responses")
|
||||||
|
|
||||||
|
val subscription =
|
||||||
|
object : Listener {
|
||||||
|
override fun onError(
|
||||||
|
error: Error,
|
||||||
|
subscriptionId: String,
|
||||||
|
relay: Relay,
|
||||||
|
) {
|
||||||
|
relayErrors[relay.url]?.let {
|
||||||
|
latch.countDown()
|
||||||
|
}
|
||||||
|
Log.d("sendAndWaitForResponse", "onError Error from relay ${relay.url} count: ${latch.count} error: $error")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRelayStateChange(
|
||||||
|
type: Relay.StateType,
|
||||||
|
relay: Relay,
|
||||||
|
subscriptionId: String?,
|
||||||
|
) {
|
||||||
|
if (type == Relay.StateType.DISCONNECT || type == Relay.StateType.EOSE) {
|
||||||
|
latch.countDown()
|
||||||
|
}
|
||||||
|
if (type == Relay.StateType.CONNECT) {
|
||||||
|
Log.d("sendAndWaitForResponse", "${type.name} Sending event to relay ${relay.url} count: ${latch.count}")
|
||||||
|
relay.sendOverride(signedEvent)
|
||||||
|
}
|
||||||
|
Log.d("sendAndWaitForResponse", "onRelayStateChange ${type.name} from relay ${relay.url} count: ${latch.count}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSendResponse(
|
||||||
|
eventId: String,
|
||||||
|
success: Boolean,
|
||||||
|
message: String,
|
||||||
|
relay: Relay,
|
||||||
|
) {
|
||||||
|
if (eventId == signedEvent.id()) {
|
||||||
|
if (success) {
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
latch.countDown()
|
||||||
|
Log.d("sendAndWaitForResponse", "onSendResponse Received response for $eventId from relay ${relay.url} count: ${latch.count} message $message success $success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(subscription)
|
||||||
|
additionalListener?.let { subscribe(it) }
|
||||||
|
|
||||||
|
val job =
|
||||||
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
send(signedEvent, relay, feedTypes, relayList, onDone)
|
||||||
|
}
|
||||||
|
job.join()
|
||||||
|
|
||||||
|
runBlocking {
|
||||||
|
latch.await(timeoutInSeconds, TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
Log.d("sendAndWaitForResponse", "countdown finished")
|
||||||
|
unsubscribe(subscription)
|
||||||
|
additionalListener?.let { unsubscribe(it) }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
fun sendFilterOnlyIfDisconnected(
|
fun sendFilterOnlyIfDisconnected(
|
||||||
subscriptionId: String = UUID.randomUUID().toString().substring(0..10),
|
subscriptionId: String = UUID.randomUUID().toString().substring(0..10),
|
||||||
filters: List<TypedFilter> = listOf(),
|
filters: List<TypedFilter> = listOf(),
|
||||||
@@ -206,6 +290,7 @@ object Client : RelayPool.Listener {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
override fun onSendResponse(
|
override fun onSendResponse(
|
||||||
eventId: String,
|
eventId: String,
|
||||||
success: Boolean,
|
success: Boolean,
|
||||||
@@ -219,6 +304,7 @@ object Client : RelayPool.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
override fun onAuth(
|
override fun onAuth(
|
||||||
relay: Relay,
|
relay: Relay,
|
||||||
challenge: String,
|
challenge: String,
|
||||||
@@ -228,6 +314,7 @@ object Client : RelayPool.Listener {
|
|||||||
GlobalScope.launch(Dispatchers.Default) { listeners.forEach { it.onAuth(relay, challenge) } }
|
GlobalScope.launch(Dispatchers.Default) { listeners.forEach { it.onAuth(relay, challenge) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
override fun onNotify(
|
override fun onNotify(
|
||||||
relay: Relay,
|
relay: Relay,
|
||||||
description: String,
|
description: String,
|
||||||
@@ -239,6 +326,7 @@ object Client : RelayPool.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
override fun onSend(
|
override fun onSend(
|
||||||
relay: Relay,
|
relay: Relay,
|
||||||
msg: String,
|
msg: String,
|
||||||
@@ -249,6 +337,7 @@ object Client : RelayPool.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
override fun onBeforeSend(
|
override fun onBeforeSend(
|
||||||
relay: Relay,
|
relay: Relay,
|
||||||
event: EventInterface,
|
event: EventInterface,
|
||||||
@@ -258,6 +347,7 @@ object Client : RelayPool.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
override fun onError(
|
override fun onError(
|
||||||
error: Error,
|
error: Error,
|
||||||
subscriptionId: String,
|
subscriptionId: String,
|
||||||
@@ -282,7 +372,7 @@ object Client : RelayPool.Listener {
|
|||||||
|
|
||||||
fun getSubscriptionFilters(subId: String): List<TypedFilter> = subscriptions[subId] ?: emptyList()
|
fun getSubscriptionFilters(subId: String): List<TypedFilter> = subscriptions[subId] ?: emptyList()
|
||||||
|
|
||||||
abstract class Listener {
|
interface Listener {
|
||||||
/** A new message was received */
|
/** A new message was received */
|
||||||
open fun onEvent(
|
open fun onEvent(
|
||||||
event: Event,
|
event: Event,
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ abstract class NostrDataSource(
|
|||||||
): Int = 31 * str1.hashCode() + str2.hashCode()
|
): Int = 31 * str1.hashCode() + str2.hashCode()
|
||||||
|
|
||||||
private val clientListener =
|
private val clientListener =
|
||||||
object : Client.Listener() {
|
object : Client.Listener {
|
||||||
override fun onEvent(
|
override fun onEvent(
|
||||||
event: Event,
|
event: Event,
|
||||||
subscriptionId: String,
|
subscriptionId: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user