diff --git a/src/main/kotlin/drills/drill02/exercise1/Client.kt b/src/main/kotlin/drills/drill02/exercise1/Client.kt new file mode 100644 index 0000000..9149bd7 --- /dev/null +++ b/src/main/kotlin/drills/drill02/exercise1/Client.kt @@ -0,0 +1,25 @@ +package drills.drill02.exercise1 + +import util.rmi.Client + +fun main() { + Client(clientHandler).start() +} + +val clientHandler = { + val chat = Client.lookup("chat") as RemoteObservable + + val observer: RemoteObserver = ChatObserver() + chat.attach(observer) + + print("Send> ") + var line = readLine() ?: "." + + while (line != ".") { + chat.notify(line) + println("Send> ") + line = readLine() ?: "." + } + + chat.detach(observer) +} diff --git a/src/main/kotlin/drills/drill02/exercise1/RemoteObservable.kt b/src/main/kotlin/drills/drill02/exercise1/RemoteObservable.kt new file mode 100644 index 0000000..30ee873 --- /dev/null +++ b/src/main/kotlin/drills/drill02/exercise1/RemoteObservable.kt @@ -0,0 +1,34 @@ +package drills.drill02.exercise1 + +import java.rmi.Remote +import java.rmi.RemoteException +import java.rmi.server.UnicastRemoteObject + +interface RemoteObservable : Remote { + @Throws(RemoteException::class) + fun attach(o: RemoteObserver) + + @Throws(RemoteException::class) + fun detach(o: RemoteObserver) + + @Throws(RemoteException::class) + fun notify(obj: Any) +} + +abstract class AbstractRemoteObservable : RemoteObservable, UnicastRemoteObject() { + private val observers = mutableListOf() + + override fun attach(o: RemoteObserver) { + observers.add(o) + } + + override fun detach(o: RemoteObserver) { + observers.remove(o) + } + + override fun notify(obj: Any) { + observers.forEach { + it.update(obj) + } + } +} diff --git a/src/main/kotlin/drills/drill02/exercise1/RemoteObserver.kt b/src/main/kotlin/drills/drill02/exercise1/RemoteObserver.kt new file mode 100644 index 0000000..afe4c17 --- /dev/null +++ b/src/main/kotlin/drills/drill02/exercise1/RemoteObserver.kt @@ -0,0 +1,16 @@ +package drills.drill02.exercise1 + +import java.rmi.Remote +import java.rmi.RemoteException +import java.rmi.server.UnicastRemoteObject + +interface RemoteObserver : Remote { + @Throws(RemoteException::class) + fun update(obj: Any) +} + +class ChatObserver : RemoteObserver, UnicastRemoteObject() { + override fun update(obj: Any) { + println("Received> ${obj as String}") + } +} diff --git a/src/main/kotlin/drills/drill02/exercise1/Server.kt b/src/main/kotlin/drills/drill02/exercise1/Server.kt new file mode 100644 index 0000000..ad67c3c --- /dev/null +++ b/src/main/kotlin/drills/drill02/exercise1/Server.kt @@ -0,0 +1,10 @@ +package drills.drill02.exercise1 + +import util.rmi.Server + +fun main() { + Server { + val chat = object : AbstractRemoteObservable() {} + Server.bind(chat, "chat") + }.start() +} diff --git a/src/main/kotlin/drills/drill02/exercise2/Client.kt b/src/main/kotlin/drills/drill02/exercise2/Client.kt new file mode 100644 index 0000000..8829c23 --- /dev/null +++ b/src/main/kotlin/drills/drill02/exercise2/Client.kt @@ -0,0 +1,26 @@ +package drills.drill02.exercise2 + +import util.rmi.Client + +fun main() { + Client(clientHandler).start() +} + +val clientHandler = { + val rev = Client.lookup("rev") as Rev + + println("Enter two numbers:") + val a = readLine()?.toInt() ?: 0 + val b = readLine()?.toInt() ?: 0 + + val sum = rev.executeTask { a + b } + println("The sum of $a and $b is $sum") + + println("Enter the number of which you want to calculate the factorial:") + val n = readLine()?.toInt() ?: 0 + + val fact = rev.executeTask { fact(n) } + println("The factorial of $n is $fact") +} + +fun fact(n: Int): Long = if (n <= 1) 1 else n * fact(n - 1) diff --git a/src/main/kotlin/drills/drill02/exercise2/Rev.kt b/src/main/kotlin/drills/drill02/exercise2/Rev.kt new file mode 100644 index 0000000..12592dc --- /dev/null +++ b/src/main/kotlin/drills/drill02/exercise2/Rev.kt @@ -0,0 +1,14 @@ +package drills.drill02.exercise2 + +import java.rmi.Remote +import java.rmi.RemoteException +import java.rmi.server.UnicastRemoteObject + +interface Rev : Remote { + @Throws(RemoteException::class) + fun executeTask(task: () -> T): T +} + +class RevImpl : Rev, UnicastRemoteObject() { + override fun executeTask(task: () -> T): T = task() +} diff --git a/src/main/kotlin/drills/drill02/exercise2/Server.kt b/src/main/kotlin/drills/drill02/exercise2/Server.kt new file mode 100644 index 0000000..9156a10 --- /dev/null +++ b/src/main/kotlin/drills/drill02/exercise2/Server.kt @@ -0,0 +1,10 @@ +package drills.drill02.exercise2 + +import util.rmi.Server + +fun main() { + Server { + val rev: Rev = RevImpl() + Server.bind(rev, "rev") + }.start() +} diff --git a/src/main/kotlin/util/rmi/Server.kt b/src/main/kotlin/util/rmi/Server.kt index 336d34d..a43b11a 100644 --- a/src/main/kotlin/util/rmi/Server.kt +++ b/src/main/kotlin/util/rmi/Server.kt @@ -25,9 +25,9 @@ class Server(private val handler: () -> Unit) { } companion object { - fun bind(remote: Remote, name: String, port: Int = 4242) { + fun bind(remote: Remote, name: String, host: String = "localhost", port: Int = 4242) { LocateRegistry.createRegistry(port) - Naming.bind("rmi://localhost:$port/$name", remote) + Naming.bind("rmi://$host:$port/$name", remote) } } }