diff --git a/zenoh-jni/src/scouting.rs b/zenoh-jni/src/scouting.rs index 59a429bb..7f219645 100644 --- a/zenoh-jni/src/scouting.rs +++ b/zenoh-jni/src/scouting.rs @@ -97,3 +97,14 @@ pub unsafe extern "C" fn Java_io_zenoh_jni_JNIScout_00024Companion_scoutViaJNI( null() }) } + +/// Frees the scout. +#[no_mangle] +#[allow(non_snake_case)] +pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIScout_00024Companion_freePtrViaJNI( + _env: JNIEnv, + _: JClass, + scout_ptr: *const Scout<()>, +) { + Arc::from_raw(scout_ptr); +} diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt index d3cfcf51..2942e4e0 100644 --- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt +++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt @@ -35,13 +35,13 @@ object Zenoh { * @param callback [Callback] to be run when receiving a [Hello] message. * @param whatAmI [WhatAmI] configuration: it indicates the role of the zenoh node sending the HELLO message. * @param config Optional [Config] for the scout. - * @return A [Scout] object. + * @return A result with the [Scout] object. */ fun scout( callback: Callback, whatAmI: Set = setOf(Peer, Router), config: Config? = null - ): Scout { + ): Result> { ZenohLoad return JNIScout.scout(whatAmI = whatAmI, callback = callback, receiver = Unit, config = config) } @@ -55,13 +55,13 @@ object Zenoh { * @param handler [Handler] to handle incoming [Hello] messages. * @param whatAmI [WhatAmI] configuration: it indicates the role of the zenoh node sending the HELLO message. * @param config Optional [Config] for the scout. - * @return A [Scout] object. + * @return A result with the [Scout] object. */ fun scout( handler: Handler, whatAmI: Set = setOf(Peer, Router), config: Config? = null - ): Scout { + ): Result> { ZenohLoad return JNIScout.scout( whatAmI = whatAmI, @@ -80,13 +80,13 @@ object Zenoh { * @param channel [Channel] upon which the incoming [Hello] messages will be piped. * @param whatAmI [WhatAmI] configuration: it indicates the role of the zenoh node sending the HELLO message. * @param config Optional [Config] for the scout. - * @return A [Scout] object. + * @return A result with the [Scout] object. */ fun scout( channel: Channel, whatAmI: Set = setOf(Peer, Router), config: Config? = null - ): Scout> { + ): Result>> { ZenohLoad val handler = ChannelHandler(channel) return JNIScout.scout( diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIScout.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIScout.kt index 7a5f0e4f..f3f51f7e 100644 --- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIScout.kt +++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIScout.kt @@ -35,13 +35,13 @@ class JNIScout(private val ptr: Long) { callback: Callback, config: Config?, receiver: R - ): Scout { + ): Result> = runCatching { val scoutCallback = JNIScoutCallback { whatAmI2: Int, id: String, locators: List -> callback.run(Hello(WhatAmI.fromInt(whatAmI2), ZenohID(id), locators)) } val binaryWhatAmI: Int = whatAmI.map { it.value }.reduce { acc, it -> acc or it } val ptr = scoutViaJNI(binaryWhatAmI, scoutCallback, config?.jniConfig?.ptr) - return Scout(receiver, JNIScout(ptr)) + Scout(receiver, JNIScout(ptr)) } @Throws(Exception::class) diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/scouting/Scout.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/scouting/Scout.kt index e7f31179..7c9f98b2 100644 --- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/scouting/Scout.kt +++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/scouting/Scout.kt @@ -22,6 +22,13 @@ import io.zenoh.jni.JNIScout * Scout spawns a task that periodically sends scout messages and waits for Hello replies. * Drop the returned Scout to stop the scouting task. * + * To launch a scout, use [io.zenoh.Zenoh.scout]: + * ```kotlin + * Zenoh.scout(callback = { hello -> + * println(hello) + * }).getOrThrow() + * ``` + * * @param R The receiver type. * @param receiver Receiver to handle incoming hello messages. */ diff --git a/zenoh-kotlin/src/commonTest/kotlin/io/zenoh/ScoutTest.kt b/zenoh-kotlin/src/commonTest/kotlin/io/zenoh/ScoutTest.kt new file mode 100644 index 00000000..62220471 --- /dev/null +++ b/zenoh-kotlin/src/commonTest/kotlin/io/zenoh/ScoutTest.kt @@ -0,0 +1,54 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +package io.zenoh + +import io.zenoh.scouting.Hello +import kotlinx.coroutines.channels.Channel +import kotlin.test.Test +import kotlin.test.assertNotNull + +class ScoutTest { + + @Test + fun `scouting is declared and undeclared properly test`() { + val scout = Zenoh.scout(Channel()).getOrThrow() + scout.close() + } + + @Test + fun `scouting detects session test`() { + + val config = Config.fromJson(""" + { + "mode": "peer", + "connect": { + "endpoints": ["tcp/localhost:7450"] + }, + } + """.trimIndent()).getOrThrow() + + val session = Session.open(config).getOrThrow() + + var hello: Hello? = null + Zenoh.scout(callback = { + hello = it + }).getOrThrow() + + Thread.sleep(1000) + + assertNotNull(hello) + session.close() + } +} \ No newline at end of file