diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/Command.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/Command.kt
index f98f998..7ae3f69 100644
--- a/src/commonMain/kotlin/net/sergeych/kiloparsec/Command.kt
+++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/Command.kt
@@ -6,7 +6,6 @@ import net.sergeych.bintools.toDataSource
import net.sergeych.bipack.BipackDecoder
import net.sergeych.bipack.BipackEncoder
import net.sergeych.kiloparsec.Command.Call
-import net.sergeych.kiloparsec.Command.Companion.unpackCall
import net.sergeych.utools.unpack
/**
@@ -27,7 +26,7 @@ import net.sergeych.utools.unpack
* [unpackResult].
*
*/
-class Command(
+open class Command(
val name: String,
val argsSerializer: KSerializer,
val resultSerializer: KSerializer
diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloInterface.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloInterface.kt
index aa20536..89ff162 100644
--- a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloInterface.kt
+++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloInterface.kt
@@ -19,7 +19,7 @@ open class KiloInterface : LocalInterface>() {
fun onConnected(f: KiloScope.()->Unit) { onConnectHandler = f }
init {
- registerError { RemoteInterface.UnknownCommand() }
+ registerError { RemoteInterface.UnknownCommand(it) }
registerError { RemoteInterface.InternalError(it) }
registerError { RemoteInterface.ClosedException(it) }
// registerError { RemoteInterface.SecurityException(it) }
diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/LocalInterface.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/LocalInterface.kt
index f28ff8b..23789cb 100644
--- a/src/commonMain/kotlin/net/sergeych/kiloparsec/LocalInterface.kt
+++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/LocalInterface.kt
@@ -67,7 +67,7 @@ open class LocalInterface : Loggable by LogTag("LocalInterface${idCounter.inc
name: String,
packedArgs: UByteArray,
): UByteArray =
- (commands[name] ?: throw RemoteInterface.UnknownCommand())
+ (commands[name] ?: throw RemoteInterface.UnknownCommand(name))
.invoke(scope, packedArgs)
diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/RemoteInterface.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/RemoteInterface.kt
index b74c712..0c2bd56 100644
--- a/src/commonMain/kotlin/net/sergeych/kiloparsec/RemoteInterface.kt
+++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/RemoteInterface.kt
@@ -40,7 +40,7 @@ interface RemoteInterface {
/**
* Command is not supported by the remote party
*/
- class UnknownCommand : RemoteException("UnknownCommand")
+ class UnknownCommand(commandName: String) : RemoteException("UnknownCommand: $commandName")
open class InternalError(code: String="0"): RemoteException("Internal error: $code")
diff --git a/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt b/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt
index a5d89d6..ee75359 100644
--- a/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt
+++ b/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt
@@ -18,6 +18,27 @@ import net.sergeych.mp_logger.*
import net.sergeych.tools.AtomicCounter
import java.time.Duration
+/**
+ * Create a ktor-based websocket server.
+ * This call install Routing and WebSockets with proper configuration.
+ *
+ * The course of action is:
+ *
+ * - create LocalInterface and populate it with functionality
+ * - call this method with localInterface
+ * - optionally, connect the same interface with TCP or UDP providers on supported platforms,
+ * in which case it might be useful to hae session creating function [createSession] separate.
+ *
+ * _Note_: [KiloInterface] as for now does not contain session creation in it as we suggest
+ * session could be transport specific.
+ *
+ * @param localInterface where the actual work is performed.
+ * @param timeout how long to wait for the connection to be established.
+ * @param path default http path to the websocket.
+ * @param serverKey optional key to authenticate the connection. If the client specify expected
+ * server key it should match of connection will not be established.
+ * @param createSession function to create a server session.
+ */
fun Application.setupWebsocketServer(
localInterface: KiloInterface,
path: String = "/kp",
diff --git a/src/ktorSocketTest/kotlin/net/sergeych/kiloparsec/adapter/InternetTest.kt b/src/ktorSocketTest/kotlin/net/sergeych/kiloparsec/adapter/InternetTest.kt
index 82ba3a5..a127a56 100644
--- a/src/ktorSocketTest/kotlin/net/sergeych/kiloparsec/adapter/InternetTest.kt
+++ b/src/ktorSocketTest/kotlin/net/sergeych/kiloparsec/adapter/InternetTest.kt
@@ -10,7 +10,7 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
-class InternetrTest {
+class InternetTest {
class TestException : Exception("test1")
@Test
@@ -46,8 +46,11 @@ class InternetrTest {
Session("unknown")
}
- val client = KiloClient() {
+ data class LocalSession(val localFoo: String)
+
+ val client = KiloClient {
addErrors(cli)
+ session { LocalSession("unknown") }
// TODO: add register error variant
connect { connectTcpDevice("localhost:$port") }
}