From 26db60a211757018c2ce768b260e009667e81b6d Mon Sep 17 00:00:00 2001 From: sergeych Date: Thu, 1 Aug 2024 02:17:45 +0200 Subject: [PATCH] readme update --- README.md | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/README.md b/README.md index 3144fa2..c581346 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ provides the following transports: | Websock server | * | | | | Websock client | * | * | * | +At the moment we're working on supporting TCP/IP on most native targets. This feature is planned to rach public beta in August and production in early september 2024. + + ## TCP/IP transport It is the fastest. JVM implementation uses nio2 async sockets and optimizes TCP socket to play @@ -26,6 +29,113 @@ We recommend to create the `KiloInterface` instance and connect it to the web # Usage +Th elibrary should be used as maven dependency, not as source. + +## Adding dependency + +### Declare maven repository: + +Add the private repository to your `build.gradle.kts`, like: + +```kotlin +repositories { + maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven") +} +``` + +### Add dependency block + +It could be, depending on your project structure, something like: + +```kotlin +val commonMain by getting { + dependencies { + api("net.sergeych:kiloparsec:0.2.3") + } +} +``` + +## Create shared interface for your server and the client + +It could be a multiplatform library that exports it or just a shared or copied source file declaring structures +and functions available, like: + +```kotlin +// Api.kt + +@Serializable +class FooArgs(val text: String,val number: Int = 42) + +// Server-side interface +val cmdSetFoo by command() +val cmdGetFoo by command() +val cmdPing by command() +val cmdCheckConnected by command() + +// client-side interface (called from the server) +val cmdPushClient by command() +``` + +## Call it from the client: + +Remember, we need to implement client interface `cmdPushClient` in our example, so we need to provide +local interace too: + +```kotlin +// Unit: no session on the client: +val client = websocketClient("wss://your.host.com/kp") { + // This is server-callable function we export: + on(cmdPushClient) { + "server push: $it" + } +} + +// If we want to collect connected state changes (this is optional) +launch { + client.connectedStateFlow.collect { + if( it ) + println("I am connected") + else + println("trying to connect...") + } +} + +// now we can call server's functions +client.call(cmdSetFoo, FooArgs("bar", 117)) +assertEquals(FooArgs("bar", 117), client.call(cmdGetFoo)) + +``` + +## Create ktor-based server + +Normally server side needs some session. It is convenient and avoid sending repeating data on each request speeding up +the protocol. With KILOPARSEC it is rather basic operation:\ + +~~~kotlin +// Our session just keeps Foo for cmd{Get|Set}Foo: +data class Session(var fooState: FooArgs?=null) + +// Let's now provide interface we export, it will be used on each connection automatically: + +// Note server interface uses Session: +val serverInterface = KiloInterface().apply { + onConnected { + // Do some initialization + session.fooState = null + } + // Exceptions are passed through the network and re-created (re-thrown) on other side: + on(cmdGetFoo) { session.fooState ?: throw IllegalStateException("foo is not yet set") } + on(cmdSetFoo) { session.fooState = it } +} + +// now create server using ktor (see ktor project for more): + +val ns: NettyApplicationEngine = embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = { + setupWebsocketServer(serverInterface) { Session() } +}).start(wait = false) + + +~~~ # Details It is not compatible with parsec family and no more based on an Universa crypto library. To better fit