EventKt is a simple and lightweight kotlin multiplatform event bus library.
The library uses Kotlin Coroutines Flow for provide you the events. Also the library provide support for remote event publishing and listening, you can check more at the remote section.
The EventKt is scoped based, this means that for you publish or listen for some event you need a EventScope.
The library provides a global scope GlobalEventScope
.
repositories {
maven {
url = "http://nexus.devsrsouza.com.br/repository/maven-public/"
}
}
dependencies {
// multiplatform
implementation("br.com.devsrsouza.eventkt:eventkt-core:0.2.0-SNAPSHOT")
}
JVM target:
implementation("br.com.devsrsouza.eventkt:eventkt-core-jvm:0.2.0-SNAPSHOT")
import br.com.devsrsouza.eventkt.scopes.GlobalEventScope
import br.com.devsrsouza.eventkt.listen
data class OnSomethingHappen(val withValue: String)
GlobalEventScope.listen<OnSomethingHappen>()
.onEach { (withValue) ->
println("Receive my event OnSomethingHappen was triggered with value: $withValue")
}.launchIn(myCoroutineScope)
GlobalEventScope.publish(OnSomethingHappen("Hello World!"))
import br.com.devsrsouza.eventkt.scopes.GlobalEventScope
import br.com.devsrsouza.eventkt.scopes.asSimple
import br.com.devsrsouza.eventkt.listen
data class OnSomethingHappen(val withValue: String)
SimpleGlobalEventScope.listen<OnSomethingHappen>(owner = this) { (withValue) ->
println("Receive my event OnSomethingHappen was triggered with value: $withValue")
}
SimpleGlobalEventScope.publish(OnSomethingHappen("Hello World!"))
import br.com.devsrsouza.eventkt.scopes.LocalEventScope
import br.com.devsrsouza.eventkt.listen
data class OnSomethingLocallyHappen(val withValue: String)
val yourScope = LocalEventScope()
yourScope.listen<OnSomethingLocallyHappen>()
.onEach { (withValue) ->
println("Receive my event OnSomethingLocallyHappen was triggered with value: $withValue")
}.launchIn(myCoroutineScope)
yourScope.publish(OnSomethingHappen("Hello Local World!"))
import br.com.devsrsouza.eventkt.scopes.GlobalEventScope
import br.com.devsrsouza.eventkt.scopes.asSimple
import br.com.devsrsouza.eventkt.listen
val singleThreadContext = newSingleThreadContext("EventReceiverThread")
val myCoroutineScope = CoroutineScope(singleThreadContext)
data class OnSomethingHappen()
val simpleEventScope = GlobalEventScope.asSimple()
simpleEventScope.listen<OnSomethingHappen>(owner = this, coroutineScope = myCoroutineScope) { (withValue) ->
println("Receive my event in thread: ${Thread.currentThread().name}")
}
GlobalEventScope.publish(OnSomethingHappen())
In Android you could receive events directly in the Main Thread (UI Thread) using simples as well.
SimpleGlobalEventScope.listen<OnSomethingHappen>(owner = this, coroutineScope = viewLifecycleOwner.lifecycleScope) {}
When using simple scope you should always unregister your owners on disable/destroy/stop a object that listen, like a Activity/Fragment/Service on Android
import br.com.devsrsouza.eventkt.scopes.asSimple
simpleEventScope.unregisterOwner(owner = this)
import br.com.devsrsouza.eventkt.scopes.asSimple
SimpleGlobalEventScope.withOwner(this) {
listen<OnSomethingHappen> {
println("Yeah!")
}
}
// unregistering
SimpleGlobalEventScope.unregister(this)
val combinedScope: EventScope = LocalEventScope() + RedisEventScope()
EventKt is design to be used with Remote event publisher, such as Redis Pub/Sub, WebsSocket, Kafka, MQTT, AMQP etc.
Remote event listen and publish require to your class/object to enconded and decoded, for this reason, you will need a encoder. EventKt provides a Kotlinx.serialization encoder implementation.
dependencies {
implementation("br.com.devsrsouza.eventkt:eventkt-remote-encoder-serialization:0.2.0-SNAPSHOT")
}
Client | Package |
---|---|
Jedis/Redis (jvm) | br.com.devsrsouza.eventkt:eventkt-remote-jvm-jedis:0.2.0-SNAPSHOT |
RabbitMQ/AMQP (jvm) | br.com.devsrsouza.eventkt:eventkt-remote-jvm-rabbitmq:0.2.0-SNAPSHOT |
Eclipse Paho/MQTT (jvm) | br.com.devsrsouza.eventkt:eventkt-remote-jvm-paho:0.2.0-SNAPSHOT |
The project ships a Jedis Redis Client implementation (jvm only).
The recommendation is to use Kotlinx.serialization encoder, in case you use it,
you will need make your events @Serializable
.
dependencies {
implementation("br.com.devsrsouza.eventkt:eventkt-remote-jvm-jedis:0.2.0-SNAPSHOT")
// encoder
implementation("br.com.devsrsouza.eventkt:eventkt-remote-encoder-serialization:0.2.0-SNAPSHOT")
}
val subscribe = Jedis("127.0.0.1").apply { connect() }
val publisher = Jedis("127.0.0.1").apply { connect() }
val redisScope = JedisEventScope(
StringSerializationRemoteEncoder(Json),
subscribe,
publisher,
channelName = "MyProjectChannelName"
)
With this scope you can publish and listen to events from remote instances.
@Serializable
data class YourEventClass(val x: String)
redisScope.listen<YourEventClass>()
.onEach { println(it) }
.launchIn(GlobalScope)