Changed RMI object callback to only be "this", instead of passing the (internal) rmiID around. The RMI-ID is used for internal rmi messages, so that a request+response can be paired.
This commit is contained in:
parent
09087b470a
commit
ed76209925
@ -746,7 +746,7 @@ open class Client<CONNECTION : Connection>(config: Configuration = Configuration
|
||||
*
|
||||
* @see RemoteObject
|
||||
*/
|
||||
suspend inline fun <reified Iface> createObject(vararg objectParameters: Any?, noinline callback: suspend (Int, Iface) -> Unit) {
|
||||
suspend inline fun <reified Iface> createObject(vararg objectParameters: Any?, noinline callback: suspend Iface.() -> Unit) {
|
||||
// NOTE: It's not possible to have reified inside a virtual function
|
||||
// https://stackoverflow.com/questions/60037849/kotlin-reified-generic-in-virtual-function
|
||||
val kryoId = serialization.getKryoIdForRmiClient(Iface::class.java)
|
||||
@ -776,7 +776,7 @@ open class Client<CONNECTION : Connection>(config: Configuration = Configuration
|
||||
*
|
||||
* @see RemoteObject
|
||||
*/
|
||||
suspend inline fun <reified Iface> createObject(noinline callback: suspend (Int, Iface) -> Unit) {
|
||||
suspend inline fun <reified Iface> createObject(noinline callback: suspend Iface.() -> Unit) {
|
||||
// NOTE: It's not possible to have reified inside a virtual function
|
||||
// https://stackoverflow.com/questions/60037849/kotlin-reified-generic-in-virtual-function
|
||||
val kryoId = serialization.getKryoIdForRmiClient(Iface::class.java)
|
||||
|
@ -648,8 +648,8 @@ open class Connection(connectionParameters: ConnectionParams<*>) {
|
||||
*
|
||||
* @see RemoteObject
|
||||
*/
|
||||
suspend fun <Iface> createObject(vararg objectParameters: Any?, callback: suspend (Int, Iface) -> Unit) {
|
||||
val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function2::class.java, callback.javaClass, 1)
|
||||
suspend fun <Iface> createObject(vararg objectParameters: Any?, callback: suspend Iface.() -> Unit) {
|
||||
val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function1::class.java, callback.javaClass, 0)
|
||||
val kryoId = endPoint.serialization.getKryoIdForRmiClient(iFaceClass)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@ -675,8 +675,8 @@ open class Connection(connectionParameters: ConnectionParams<*>) {
|
||||
*
|
||||
* @see RemoteObject
|
||||
*/
|
||||
suspend fun <Iface> createObject(callback: suspend (Int, Iface) -> Unit) {
|
||||
val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function2::class.java, callback.javaClass, 1)
|
||||
suspend fun <Iface> createObject(callback: suspend Iface.() -> Unit) {
|
||||
val iFaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(Function1::class.java, callback.javaClass, 0)
|
||||
val kryoId = endPoint.serialization.getKryoIdForRmiClient(iFaceClass)
|
||||
|
||||
rmiConnectionSupport.createRemoteObject(this, kryoId, null, callback)
|
||||
|
@ -74,7 +74,7 @@ internal class RmiManagerConnections<CONNECTION: Connection>(logger: KLogger,
|
||||
/**
|
||||
* on the "client" to create a connection-specific remote object (that exists on the server)
|
||||
*/
|
||||
suspend fun <Iface> createRemoteObject(connection: Connection, kryoId: Int, objectParameters: Array<Any?>?, callback: suspend (Int, Iface) -> Unit) {
|
||||
suspend fun <Iface> createRemoteObject(connection: Connection, kryoId: Int, objectParameters: Array<Any?>?, callback: suspend Iface.() -> Unit) {
|
||||
val callbackId = rmiGlobalSupport.registerCallback(callback)
|
||||
|
||||
// There is no rmiID yet, because we haven't created it!
|
||||
|
@ -18,12 +18,7 @@ package dorkbox.network.rmi
|
||||
import dorkbox.network.connection.Connection
|
||||
import dorkbox.network.connection.EndPoint
|
||||
import dorkbox.network.connection.ListenerManager
|
||||
import dorkbox.network.rmi.messages.ConnectionObjectCreateRequest
|
||||
import dorkbox.network.rmi.messages.ConnectionObjectCreateResponse
|
||||
import dorkbox.network.rmi.messages.GlobalObjectCreateRequest
|
||||
import dorkbox.network.rmi.messages.GlobalObjectCreateResponse
|
||||
import dorkbox.network.rmi.messages.MethodRequest
|
||||
import dorkbox.network.rmi.messages.MethodResponse
|
||||
import dorkbox.network.rmi.messages.*
|
||||
import dorkbox.network.serialization.Serialization
|
||||
import dorkbox.util.classes.ClassHelper
|
||||
import kotlinx.coroutines.launch
|
||||
@ -81,11 +76,11 @@ internal class RmiManagerGlobal<CONNECTION : Connection>(logger: KLogger,
|
||||
private val remoteObjectCreationCallbacks = RemoteObjectStorage(logger)
|
||||
|
||||
|
||||
internal fun <Iface> registerCallback(callback: suspend (Int, Iface) -> Unit): Int {
|
||||
internal fun <Iface> registerCallback(callback: suspend Iface.() -> Unit): Int {
|
||||
return remoteObjectCreationCallbacks.register(callback)
|
||||
}
|
||||
|
||||
private fun removeCallback(callbackId: Int): suspend (Int, Any) -> Unit {
|
||||
private fun removeCallback(callbackId: Int): suspend Any.() -> Unit {
|
||||
// callback's area always correct, because we track them ourselves.
|
||||
return remoteObjectCreationCallbacks.remove(callbackId)!!
|
||||
}
|
||||
@ -125,7 +120,7 @@ internal class RmiManagerGlobal<CONNECTION : Connection>(logger: KLogger,
|
||||
connection: CONNECTION,
|
||||
isGlobal: Boolean,
|
||||
rmiId: Int,
|
||||
callback: suspend (Int, Any) -> Unit,
|
||||
callback: suspend Any.() -> Unit,
|
||||
serialization: Serialization) {
|
||||
|
||||
// we only create the proxy + execute the callback if the RMI id is valid!
|
||||
@ -134,7 +129,7 @@ internal class RmiManagerGlobal<CONNECTION : Connection>(logger: KLogger,
|
||||
return
|
||||
}
|
||||
|
||||
val interfaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(RemoteObjectCallback::class.java, callback.javaClass, 1)
|
||||
val interfaceClass = ClassHelper.getGenericParameterAsClassForSuperClass(RemoteObjectCallback::class.java, callback.javaClass, 0)
|
||||
|
||||
// create the client-side proxy object, if possible. This MUST be an object that is saved for the connection
|
||||
var proxyObject = connection.rmiConnectionSupport.getProxyObject(rmiId)
|
||||
@ -147,7 +142,7 @@ internal class RmiManagerGlobal<CONNECTION : Connection>(logger: KLogger,
|
||||
// this should be executed on a NEW coroutine!
|
||||
endPoint.actionDispatch.launch {
|
||||
try {
|
||||
callback(rmiId, proxyObject)
|
||||
callback(proxyObject)
|
||||
} catch (e: Exception) {
|
||||
ListenerManager.cleanStackTrace(e)
|
||||
endPoint.listenerManager.notifyError(e)
|
||||
|
@ -100,16 +100,16 @@ class SerializationValidationTest : BaseTest() {
|
||||
|
||||
client.onConnect { connection ->
|
||||
connection.logger.error("Connected")
|
||||
connection.createObject<TestObject> { rmiId, remoteObject ->
|
||||
connection.createObject<TestObject> {
|
||||
connection.logger.error("Starting test")
|
||||
remoteObject.setValue(43.21f)
|
||||
setValue(43.21f)
|
||||
|
||||
// Normal remote method call.
|
||||
Assert.assertEquals(43.21f, remoteObject.other(), .0001f)
|
||||
Assert.assertEquals(43.21f, other(), .0001f)
|
||||
|
||||
// When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because
|
||||
// that is where that object actually exists.
|
||||
connection.send(remoteObject)
|
||||
connection.send(this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,16 +147,16 @@ class SerializationValidationTest : BaseTest() {
|
||||
|
||||
client.onConnect { connection ->
|
||||
connection.logger.error("Connected")
|
||||
connection.createObject<TestObject> { rmiId, remoteObject ->
|
||||
connection.createObject<TestObject> {
|
||||
connection.logger.error("Starting test")
|
||||
remoteObject.setValue(43.21f)
|
||||
setValue(43.21f)
|
||||
|
||||
// Normal remote method call.
|
||||
Assert.assertEquals(43.21f, remoteObject.other(), .0001f)
|
||||
Assert.assertEquals(43.21f, other(), .0001f)
|
||||
|
||||
// When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because
|
||||
// that is where that object actually exists.
|
||||
connection.send(remoteObject)
|
||||
connection.send(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,17 +90,17 @@ class RmiNestedTest : BaseTest() {
|
||||
|
||||
client.onConnect { connection ->
|
||||
connection.logger.error("Connected")
|
||||
connection.createObject<TestObject> { rmiId, remoteObject ->
|
||||
connection.createObject<TestObject> {
|
||||
connection.logger.error("Starting test")
|
||||
remoteObject.setValue(43.21f)
|
||||
setValue(43.21f)
|
||||
|
||||
// Normal remote method call.
|
||||
Assert.assertEquals(43.21f, remoteObject.other(), .0001f)
|
||||
Assert.assertEquals(43.21f, other(), .0001f)
|
||||
|
||||
// Make a remote method call that returns another remote proxy object.
|
||||
// the "test" object exists in the REMOTE side, as does the "OtherObject" that is created.
|
||||
// here we have a proxy to both of them.
|
||||
val otherObject: OtherObject = remoteObject.getOtherObject()
|
||||
val otherObject: OtherObject = getOtherObject()
|
||||
|
||||
// Normal remote method call on the second object.
|
||||
otherObject.setValue(12.34f)
|
||||
@ -109,7 +109,7 @@ class RmiNestedTest : BaseTest() {
|
||||
|
||||
|
||||
// make sure the "local" object and the "remote" object have the same values
|
||||
Assert.assertEquals(12.34f, remoteObject.getOtherValue(), .0001f)
|
||||
Assert.assertEquals(12.34f, getOtherValue(), .0001f)
|
||||
|
||||
|
||||
// When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because
|
||||
@ -157,17 +157,17 @@ class RmiNestedTest : BaseTest() {
|
||||
|
||||
client.onConnect { connection ->
|
||||
connection.logger.error("Connected")
|
||||
connection.createObject<TestObject> { rmiId, remoteObject ->
|
||||
connection.createObject<TestObject> {
|
||||
connection.logger.error("Starting test")
|
||||
remoteObject.setValue(43.21f)
|
||||
setValue(43.21f)
|
||||
|
||||
// Normal remote method call.
|
||||
Assert.assertEquals(43.21f, remoteObject.other(), .0001f)
|
||||
Assert.assertEquals(43.21f, other(), .0001f)
|
||||
|
||||
// Make a remote method call that returns another remote proxy object.
|
||||
// the "test" object exists in the REMOTE side, as does the "OtherObject" that is created.
|
||||
// here we have a proxy to both of them.
|
||||
val otherObject: OtherObject = remoteObject.getOtherObject()
|
||||
val otherObject: OtherObject = getOtherObject()
|
||||
|
||||
// Normal remote method call on the second object.
|
||||
otherObject.setValue(12.34f)
|
||||
@ -176,7 +176,7 @@ class RmiNestedTest : BaseTest() {
|
||||
|
||||
|
||||
// make sure the "local" object and the "remote" object have the same values
|
||||
Assert.assertEquals(12.34f, remoteObject.getOtherValue(), .0001f)
|
||||
Assert.assertEquals(12.34f, getOtherValue(), .0001f)
|
||||
|
||||
|
||||
// When a proxy object is sent, the other side receives its ACTUAL object (not a proxy of it), because
|
||||
@ -224,15 +224,15 @@ class RmiNestedTest : BaseTest() {
|
||||
|
||||
client.onConnect { connection ->
|
||||
connection.logger.error("Connected")
|
||||
connection.createObject<TestObject> { rmiId, remoteObject ->
|
||||
connection.createObject<TestObject> {
|
||||
connection.logger.error("Starting test")
|
||||
remoteObject.setOtherValue(43.21f)
|
||||
setOtherValue(43.21f)
|
||||
|
||||
// Normal remote method call.
|
||||
Assert.assertEquals(43.21f, remoteObject.getOtherValue(), .0001f)
|
||||
Assert.assertEquals(43.21f, getOtherValue(), .0001f)
|
||||
|
||||
// real object
|
||||
val otherObject: OtherObject = remoteObject.getOtherObject()
|
||||
val otherObject: OtherObject = getOtherObject()
|
||||
|
||||
// Normal remote method call on the second object.
|
||||
val value = otherObject.value()
|
||||
@ -264,15 +264,15 @@ class RmiNestedTest : BaseTest() {
|
||||
|
||||
server.onConnect { connection ->
|
||||
connection.logger.error("Connected")
|
||||
connection.createObject<TestObject> { rmiId, remoteObject ->
|
||||
connection.createObject<TestObject> {
|
||||
connection.logger.error("Starting test")
|
||||
remoteObject.setOtherValue(43.21f)
|
||||
setOtherValue(43.21f)
|
||||
|
||||
// Normal remote method call.
|
||||
Assert.assertEquals(43.21f, remoteObject.getOtherValue(), .0001f)
|
||||
Assert.assertEquals(43.21f, getOtherValue(), .0001f)
|
||||
|
||||
// real object
|
||||
val otherObject: OtherObject = remoteObject.getOtherObject()
|
||||
val otherObject: OtherObject = getOtherObject()
|
||||
|
||||
// Normal remote method call on the second object.
|
||||
val value = otherObject.value()
|
||||
|
@ -143,9 +143,9 @@ class RmiSimpleTest : BaseTest() {
|
||||
|
||||
server.logger.error("Starting test for: Server -> Client")
|
||||
// NOTE: THIS IS BI-DIRECTIONAL!
|
||||
connection.createObject<TestCow>(123) { rmiId, remoteObject ->
|
||||
connection.createObject<TestCow>(123) {
|
||||
server.logger.error("Running test for: Server -> Client")
|
||||
RmiCommonTest.runTests(connection, remoteObject, 123)
|
||||
RmiCommonTest.runTests(connection, this, 123)
|
||||
server.logger.error("Done with test for: Server -> Client")
|
||||
}
|
||||
}
|
||||
@ -160,9 +160,9 @@ class RmiSimpleTest : BaseTest() {
|
||||
addEndPoint(client)
|
||||
|
||||
client.onConnect { connection ->
|
||||
connection.createObject<TestCow>(23) { rmiId, remoteObject ->
|
||||
connection.createObject<TestCow>(23) {
|
||||
client.logger.error("Running test for: Client -> Server")
|
||||
RmiCommonTest.runTests(connection, remoteObject, 23)
|
||||
RmiCommonTest.runTests(connection, this, 23)
|
||||
client.logger.error("Done with test for: Client -> Server")
|
||||
}
|
||||
}
|
||||
@ -219,9 +219,9 @@ class RmiSimpleTest : BaseTest() {
|
||||
server.logger.error("Finished test for: Client -> Server")
|
||||
|
||||
// normally this is in the 'connected', but we do it here, so that it's more linear and easier to debug
|
||||
connection.createObject<TestCow>(4) { rmiId, remoteObject ->
|
||||
connection.createObject<TestCow>(4) {
|
||||
server.logger.error("Running test for: Server -> Client")
|
||||
RmiCommonTest.runTests(connection, remoteObject, 4)
|
||||
RmiCommonTest.runTests(connection, this, 4)
|
||||
server.logger.error("Done with test for: Server -> Client")
|
||||
}
|
||||
}
|
||||
@ -256,9 +256,9 @@ class RmiSimpleTest : BaseTest() {
|
||||
client.logger.error("Starting test for: Client -> Server")
|
||||
|
||||
// this creates a GLOBAL object on the server (instead of a connection specific object)
|
||||
client.createObject<TestCow>(44) { rmiId, remoteObject ->
|
||||
client.createObject<TestCow>(44) {
|
||||
client.logger.error("Running test for: Client -> Server")
|
||||
RmiCommonTest.runTests(client.connection, remoteObject, 44)
|
||||
RmiCommonTest.runTests(client.connection, this, 44)
|
||||
client.logger.error("Done with test for: Client -> Server")
|
||||
}
|
||||
}
|
||||
|
@ -78,12 +78,12 @@ object TestClient {
|
||||
client.onConnect { connection ->
|
||||
connection.logger.error("Starting test for: Client -> Server")
|
||||
|
||||
connection.createObject<TestCow>(124123) { _, remoteObject ->
|
||||
RmiCommonTest.runTests(connection, remoteObject, 124123)
|
||||
connection.createObject<TestCow>(124123) {
|
||||
RmiCommonTest.runTests(connection, this, 124123)
|
||||
connection.logger.error("DONE")
|
||||
|
||||
// now send this remote object ACROSS the wire to the server (on the server, this is where the IMPLEMENTATION lives)
|
||||
connection.send(remoteObject)
|
||||
connection.send(this)
|
||||
|
||||
client.close()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user