Move serializer to endpoint parameter

This commit is contained in:
Alexander Nozik 2021-06-20 14:46:02 +03:00
parent e3ea2304ef
commit 6e4bf51a6f
22 changed files with 172 additions and 200 deletions

View File

@ -1,29 +1,22 @@
plugins { plugins {
id("ru.mipt.npm.gradle.project") id("ru.mipt.npm.gradle.project")
kotlin("jvm") apply false
kotlin("js") apply false
} }
val dataforgeVersion: String by extra("0.4.0-dev-8") val dataforgeVersion: String by extra("0.4.3")
val ktorVersion: String by extra(ru.mipt.npm.gradle.KScienceVersions.ktorVersion) val ktorVersion: String by extra(ru.mipt.npm.gradle.KScienceVersions.ktorVersion)
val rsocketVersion by extra("0.12.0") val rsocketVersion by extra("0.12.0")
allprojects { allprojects {
repositories {
mavenLocal()
//maven("http://maven.jzy3d.org/releases")
maven(url = "https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
maven("https://kotlin.bintray.com/js-externals")
maven("https://dl.bintray.com/rsocket-admin/RSocket")
//maven("https://maven.pkg.github.com/altavir/ktor-client-sse")
}
group = "ru.mipt.npm" group = "ru.mipt.npm"
version = "0.1.0" version = "0.1.0"
repositories{
jcenter()
}
} }
ksciencePublish { ksciencePublish {
github("controls.kt") github("controls.kt")
space()
} }
apiValidation { apiValidation {

View File

@ -5,14 +5,13 @@ import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import ru.mipt.npm.magix.api.MagixEndpoint
import space.kscience.dataforge.context.error import space.kscience.dataforge.context.error
import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.logger
import space.kscience.dataforge.control.controllers.DeviceManager import space.kscience.dataforge.control.controllers.DeviceManager
import space.kscience.dataforge.control.controllers.respondMessage import space.kscience.dataforge.control.controllers.respondMessage
import space.kscience.dataforge.control.messages.DeviceMessage import space.kscience.dataforge.control.messages.DeviceMessage
import space.kscience.dataforge.magix.api.MagixEndpoint
import space.kscience.dataforge.magix.api.MagixMessage import space.kscience.dataforge.magix.api.MagixMessage
import space.kscience.dataforge.magix.api.MagixProcessor
public const val DATAFORGE_MAGIX_FORMAT: String = "dataforge" public const val DATAFORGE_MAGIX_FORMAT: String = "dataforge"
@ -27,10 +26,10 @@ private fun generateId(request: MagixMessage<DeviceMessage>): String = if (reque
* Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1) * Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1)
*/ */
public fun DeviceManager.launchMagixClient( public fun DeviceManager.launchMagixClient(
endpoint: MagixEndpoint, endpoint: MagixEndpoint<DeviceMessage>,
endpointID: String = DATAFORGE_MAGIX_FORMAT, endpointID: String = DATAFORGE_MAGIX_FORMAT,
): Job = context.launch { ): Job = context.launch {
endpoint.subscribe(DeviceMessage.serializer()).onEach { request -> endpoint.subscribe().onEach { request ->
//TODO analyze action //TODO analyze action
val responsePayload = respondMessage(request.payload) val responsePayload = respondMessage(request.payload)
@ -41,9 +40,9 @@ public fun DeviceManager.launchMagixClient(
origin = endpointID, origin = endpointID,
payload = responsePayload payload = responsePayload
) )
endpoint.broadcast(DeviceMessage.serializer(), response) endpoint.broadcast(response)
}.catch { error -> }.catch { error ->
logger.error(error){"Error while responding to message"} logger.error(error) { "Error while responding to message" }
}.launchIn(this) }.launchIn(this)
controller.messageOutput().onEach { payload -> controller.messageOutput().onEach { payload ->
@ -54,13 +53,8 @@ public fun DeviceManager.launchMagixClient(
payload = payload payload = payload
) )
}.catch { error -> }.catch { error ->
logger.error(error){"Error while sending a message"} logger.error(error) { "Error while sending a message" }
}.launchIn(this) }.launchIn(this)
} }
public fun DeviceManager.asMagixProcessor(endpointID: String = "dataforge"): MagixProcessor = object : MagixProcessor {
override fun process(endpoint: MagixEndpoint): Job = launchMagixClient(endpoint, endpointID)
}

View File

@ -1,21 +0,0 @@
plugins {
id("ru.mipt.npm.gradle.mpp")
`maven-publish`
}
kscience{
useSerialization {
json()
}
}
kotlin {
sourceSets {
commonMain {
dependencies {
implementation(project(":magix:magix-server"))
implementation(project(":controls-core"))
}
}
}
}

View File

@ -17,13 +17,14 @@ dependencies{
implementation(project(":controls-server")) implementation(project(":controls-server"))
implementation(project(":controls-magix-client")) implementation(project(":controls-magix-client"))
implementation("no.tornado:tornadofx:1.7.20") implementation("no.tornado:tornadofx:1.7.20")
implementation("space.kscience:plotlykt-server:0.4.0-dev-2") implementation("space.kscience:plotlykt-server:0.4.2")
implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6") implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6")
} }
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach { tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions { kotlinOptions {
jvmTarget = "11" jvmTarget = "11"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
} }
} }

View File

@ -1,4 +1,4 @@
package space.kscience.dataforge.control.demo package ru.mipt.npm.controls.demo
import io.ktor.server.engine.ApplicationEngine import io.ktor.server.engine.ApplicationEngine
import javafx.scene.Parent import javafx.scene.Parent

View File

@ -1,4 +1,4 @@
package space.kscience.dataforge.control.demo package ru.mipt.npm.controls.demo
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job

View File

@ -1,4 +1,4 @@
package space.kscience.dataforge.control.demo package ru.mipt.npm.controls.demo
import io.ktor.server.engine.ApplicationEngine import io.ktor.server.engine.ApplicationEngine
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*

View File

@ -1,4 +1,4 @@
package space.kscience.dataforge.control.demo package ru.mipt.npm.controls.demo
import com.github.ricky12awesome.jss.encodeToSchema import com.github.ricky12awesome.jss.encodeToSchema
import com.github.ricky12awesome.jss.globalJson import com.github.ricky12awesome.jss.globalJson

View File

@ -1,44 +0,0 @@
package space.kscience.dataforge.magix.api
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
/**
* Inwards API of magix endpoint used to build services
*/
public interface MagixEndpoint {
/**
* Subscribe to a [Flow] of messages using specific [payloadSerializer]
*/
public fun <T> subscribe(
payloadSerializer: KSerializer<T>,
filter: MagixMessageFilter = MagixMessageFilter.ALL,
): Flow<MagixMessage<T>>
/**
* Send an event using specific [payloadSerializer]
*/
public suspend fun <T> broadcast(
payloadSerializer: KSerializer<T>,
message: MagixMessage<T>,
)
public companion object {
public const val DEFAULT_MAGIX_WS_PORT: Int = 7777
public const val DEFAULT_MAGIX_RAW_PORT: Int = 7778
public val magixJson: Json = Json{
ignoreUnknownKeys = true
encodeDefaults = false
}
}
}
public fun MagixEndpoint.subscribe(
filter: MagixMessageFilter = MagixMessageFilter.ALL,
): Flow<MagixMessage<JsonElement>> = subscribe(JsonElement.serializer(),filter)
public suspend fun MagixEndpoint.broadcast(message: MagixMessage<JsonElement>): Unit =
broadcast(JsonElement.serializer(), message)

View File

@ -1,60 +0,0 @@
package space.kscience.dataforge.magix.api
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.JsonElement
public fun interface MagixProcessor {
public fun process(endpoint: MagixEndpoint): Job
public companion object {
/**
* A converter from one (or several) format to another. It captures all events with the given filter then transforms it
* with given [transformer] and sends back to the loop with given [outputFormat].
*
* If [newOrigin] is not null, it is used as a replacement for old [MagixMessage.origin] tag.
*/
public fun <T : Any, R : Any> convert(
scope: CoroutineScope,
filter: MagixMessageFilter,
outputFormat: String,
inputSerializer: KSerializer<T>,
outputSerializer: KSerializer<R>,
newOrigin: String? = null,
transformer: suspend (T) -> R,
): MagixProcessor = MagixProcessor { endpoint ->
endpoint.subscribe(inputSerializer, filter).onEach { message ->
val newPayload = transformer(message.payload)
val transformed: MagixMessage<R> = MagixMessage(
outputFormat,
newOrigin ?: message.origin,
newPayload,
message.target,
message.id,
message.parentId,
message.user
)
endpoint.broadcast(outputSerializer, transformed)
}.launchIn(scope)
}
}
public fun convert(
scope: CoroutineScope,
filter: MagixMessageFilter,
outputFormat: String,
newOrigin: String? = null,
transformer: suspend (JsonElement) -> JsonElement,
): MagixProcessor = convert(
scope,
filter,
outputFormat,
JsonElement.serializer(),
JsonElement.serializer(),
newOrigin,
transformer
)
}

View File

@ -0,0 +1,67 @@
package ru.mipt.npm.magix.api
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import space.kscience.dataforge.magix.api.MagixMessage
import space.kscience.dataforge.magix.api.MagixMessageFilter
import space.kscience.dataforge.magix.api.replacePayload
/**
* Inwards API of magix endpoint used to build services
*/
public interface MagixEndpoint<T> {
/**
* Subscribe to a [Flow] of messages
*/
public fun subscribe(
filter: MagixMessageFilter = MagixMessageFilter.ALL,
): Flow<MagixMessage<T>>
/**
* Send an event
*/
public suspend fun broadcast(
message: MagixMessage<T>,
)
public companion object {
public const val DEFAULT_MAGIX_WS_PORT: Int = 7777
public const val DEFAULT_MAGIX_RAW_PORT: Int = 7778
public val magixJson: Json = Json {
ignoreUnknownKeys = true
encodeDefaults = false
}
}
}
/**
* Specialize this raw json endpoint to use specific serializer
*/
public fun <T : Any> MagixEndpoint<JsonElement>.specialize(
payloadSerializer: KSerializer<T>
): MagixEndpoint<T> = object : MagixEndpoint<T> {
override fun subscribe(
filter: MagixMessageFilter
): Flow<MagixMessage<T>> = this@specialize.subscribe(filter).map { message ->
message.replacePayload { payload ->
MagixEndpoint.magixJson.decodeFromJsonElement(payloadSerializer, payload)
}
}
override suspend fun broadcast(message: MagixMessage<T>) {
this@specialize.broadcast(
message.replacePayload { payload ->
MagixEndpoint.magixJson.encodeToJsonElement(
payloadSerializer,
payload
)
}
)
}
}

View File

@ -30,3 +30,10 @@ public data class MagixMessage<T>(
val user: JsonElement? = null, val user: JsonElement? = null,
val action: String? = null val action: String? = null
) )
/**
* Create message with same field but replaced payload
*/
@Suppress("UNCHECKED_CAST")
public fun <T, R> MagixMessage<T>.replacePayload(payloadTransform: (T) -> R): MagixMessage<R> =
MagixMessage(format, origin, payloadTransform(payload), target, id, parentId, user, action)

View File

@ -0,0 +1,31 @@
package space.kscience.dataforge.magix.api
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import ru.mipt.npm.magix.api.MagixEndpoint
/**
* Launch magix message converter service
*/
public fun <T, R> CoroutineScope.launchMagixConverter(
inputEndpoint: MagixEndpoint<T>,
outputEndpoint: MagixEndpoint<R>,
filter: MagixMessageFilter,
outputFormat: String,
newOrigin: String? = null,
transformer: suspend (T) -> R,
): Job = inputEndpoint.subscribe(filter).onEach { message->
val newPayload = transformer(message.payload)
val transformed: MagixMessage<R> = MagixMessage(
outputFormat,
newOrigin ?: message.origin,
newPayload,
message.target,
message.id,
message.parentId,
message.user
)
outputEndpoint.broadcast(transformed)
}.launchIn(this)

View File

@ -17,10 +17,10 @@ public interface MagixClient<T> {
Flow.Publisher<MagixMessage<T>> subscribe(); Flow.Publisher<MagixMessage<T>> subscribe();
static MagixClient<JsonElement> rSocketTcp(String host, int port) { static MagixClient<JsonElement> rSocketTcp(String host, int port) {
return ControlsMagixClient.Companion.rSocketTcp(host, port); return ControlsMagixClient.Companion.rSocketTcp(host, port, JsonElement.Companion.serializer());
} }
static MagixClient<JsonElement> rSocketWs(String host, int port, String path) { static MagixClient<JsonElement> rSocketWs(String host, int port, String path) {
return ControlsMagixClient.Companion.rSocketWs(host, port, path); return ControlsMagixClient.Companion.rSocketWs(host, port, JsonElement.Companion.serializer(), path);
} }
} }

View File

@ -3,8 +3,7 @@ package ru.mipt.npm.magix.client
import kotlinx.coroutines.jdk9.asPublisher import kotlinx.coroutines.jdk9.asPublisher
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.JsonElement import ru.mipt.npm.magix.api.MagixEndpoint
import space.kscience.dataforge.magix.api.MagixEndpoint
import space.kscience.dataforge.magix.api.MagixMessage import space.kscience.dataforge.magix.api.MagixMessage
import space.kscience.dataforge.magix.api.MagixMessageFilter import space.kscience.dataforge.magix.api.MagixMessageFilter
import space.kscience.dataforge.magix.service.RSocketMagixEndpoint import space.kscience.dataforge.magix.service.RSocketMagixEndpoint
@ -12,31 +11,39 @@ import space.kscience.dataforge.magix.service.withTcp
import java.util.concurrent.Flow import java.util.concurrent.Flow
public class ControlsMagixClient<T>( public class ControlsMagixClient<T>(
private val endpoint: MagixEndpoint, private val endpoint: MagixEndpoint<T>,
private val filter: MagixMessageFilter, private val filter: MagixMessageFilter,
private val serializer: KSerializer<T>,
) : MagixClient<T> { ) : MagixClient<T> {
override fun broadcast(msg: MagixMessage<T>): Unit = runBlocking { override fun broadcast(msg: MagixMessage<T>): Unit = runBlocking {
endpoint.broadcast(serializer, msg) endpoint.broadcast(msg)
} }
override fun subscribe(): Flow.Publisher<MagixMessage<T>> = endpoint.subscribe(serializer, filter).asPublisher() override fun subscribe(): Flow.Publisher<MagixMessage<T>> = endpoint.subscribe(filter).asPublisher()
public companion object { public companion object {
public fun rSocketTcp(host: String, port: Int): ControlsMagixClient<JsonElement> { public fun <T> rSocketTcp(
host: String,
port: Int,
payloadSerializer: KSerializer<T>
): ControlsMagixClient<T> {
val endpoint = runBlocking { val endpoint = runBlocking {
RSocketMagixEndpoint.withTcp(host, port) RSocketMagixEndpoint.withTcp(host, port, payloadSerializer)
} }
return ControlsMagixClient(endpoint, MagixMessageFilter(), JsonElement.serializer()) return ControlsMagixClient(endpoint, MagixMessageFilter())
} }
public fun rSocketWs(host: String, port: Int, path: String = "/rsocket"): ControlsMagixClient<JsonElement> { public fun <T> rSocketWs(
host: String,
port: Int,
payloadSerializer: KSerializer<T>,
path: String = "/rsocket"
): ControlsMagixClient<T> {
val endpoint = runBlocking { val endpoint = runBlocking {
RSocketMagixEndpoint.withWebSockets(host, port, path) RSocketMagixEndpoint.withWebSockets(host, port, payloadSerializer, path)
} }
return ControlsMagixClient(endpoint, MagixMessageFilter(), JsonElement.serializer()) return ControlsMagixClient(endpoint, MagixMessageFilter())
} }
} }
} }

View File

@ -11,8 +11,11 @@ import io.rsocket.kotlin.transport.ktor.serverTransport
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import space.kscience.dataforge.magix.api.MagixEndpoint.Companion.DEFAULT_MAGIX_RAW_PORT import ru.mipt.npm.magix.api.MagixEndpoint.Companion.DEFAULT_MAGIX_RAW_PORT
import space.kscience.dataforge.magix.api.MagixEndpoint.Companion.DEFAULT_MAGIX_WS_PORT import ru.mipt.npm.magix.api.MagixEndpoint.Companion.DEFAULT_MAGIX_WS_PORT
import ru.mipt.npm.magix.server.GenericMagixMessage
import ru.mipt.npm.magix.server.magixAcceptor
import ru.mipt.npm.magix.server.magixModule
@OptIn(KtorExperimentalAPI::class) @OptIn(KtorExperimentalAPI::class)
public fun CoroutineScope.startMagixServer( public fun CoroutineScope.startMagixServer(

View File

@ -1,4 +1,4 @@
package space.kscience.dataforge.magix.server package ru.mipt.npm.magix.server
import io.ktor.application.* import io.ktor.application.*
import io.ktor.features.CORS import io.ktor.features.CORS
@ -25,10 +25,12 @@ import kotlinx.coroutines.flow.*
import kotlinx.html.* import kotlinx.html.*
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import space.kscience.dataforge.magix.api.MagixEndpoint.Companion.magixJson import ru.mipt.npm.magix.api.MagixEndpoint.Companion.magixJson
import space.kscience.dataforge.magix.api.MagixMessage import space.kscience.dataforge.magix.api.MagixMessage
import space.kscience.dataforge.magix.api.MagixMessageFilter import space.kscience.dataforge.magix.api.MagixMessageFilter
import space.kscience.dataforge.magix.api.filter import space.kscience.dataforge.magix.api.filter
import space.kscience.dataforge.magix.server.SseEvent
import space.kscience.dataforge.magix.server.respondSse
import java.util.* import java.util.*
public typealias GenericMagixMessage = MagixMessage<JsonElement> public typealias GenericMagixMessage = MagixMessage<JsonElement>

View File

@ -2,7 +2,6 @@ package space.kscience.dataforge.magix.service
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.features.websocket.WebSockets import io.ktor.client.features.websocket.WebSockets
import io.ktor.util.KtorExperimentalAPI
import io.rsocket.kotlin.RSocket import io.rsocket.kotlin.RSocket
import io.rsocket.kotlin.core.RSocketConnector import io.rsocket.kotlin.core.RSocketConnector
import io.rsocket.kotlin.core.RSocketConnectorBuilder import io.rsocket.kotlin.core.RSocketConnectorBuilder
@ -15,19 +14,19 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import space.kscience.dataforge.magix.api.MagixEndpoint import ru.mipt.npm.magix.api.MagixEndpoint
import space.kscience.dataforge.magix.api.MagixMessage import space.kscience.dataforge.magix.api.MagixMessage
import space.kscience.dataforge.magix.api.MagixMessageFilter import space.kscience.dataforge.magix.api.MagixMessageFilter
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
public class RSocketMagixEndpoint( public class RSocketMagixEndpoint<T>(
private val coroutineContext: CoroutineContext, private val coroutineContext: CoroutineContext,
private val payloadSerializer: KSerializer<T>,
private val rSocket: RSocket, private val rSocket: RSocket,
) : MagixEndpoint { ) : MagixEndpoint<T> {
override fun <T> subscribe( override fun subscribe(
payloadSerializer: KSerializer<T>,
filter: MagixMessageFilter, filter: MagixMessageFilter,
): Flow<MagixMessage<T>> { ): Flow<MagixMessage<T>> {
val serializer = MagixMessage.serializer(payloadSerializer) val serializer = MagixMessage.serializer(payloadSerializer)
@ -36,7 +35,7 @@ public class RSocketMagixEndpoint(
return flow.map { MagixEndpoint.magixJson.decodeFromString(serializer, it.data.readText()) } return flow.map { MagixEndpoint.magixJson.decodeFromString(serializer, it.data.readText()) }
} }
override suspend fun <T> broadcast(payloadSerializer: KSerializer<T>, message: MagixMessage<T>) { override suspend fun broadcast(message: MagixMessage<T>) {
withContext(coroutineContext) { withContext(coroutineContext) {
val serializer = MagixMessage.serializer(payloadSerializer) val serializer = MagixMessage.serializer(payloadSerializer)
val payload = buildPayload { data(MagixEndpoint.magixJson.encodeToString(serializer, message)) } val payload = buildPayload { data(MagixEndpoint.magixJson.encodeToString(serializer, message)) }
@ -52,13 +51,13 @@ public class RSocketMagixEndpoint(
connectionConfig(rSocketConfig) connectionConfig(rSocketConfig)
} }
@OptIn(KtorExperimentalAPI::class) public suspend fun <T> withWebSockets(
public suspend fun withWebSockets(
host: String, host: String,
port: Int, port: Int,
payloadSerializer: KSerializer<T>,
path: String = "/rsocket", path: String = "/rsocket",
rSocketConfig: RSocketConnectorBuilder.ConnectionConfigBuilder.() -> Unit = {}, rSocketConfig: RSocketConnectorBuilder.ConnectionConfigBuilder.() -> Unit = {},
): RSocketMagixEndpoint { ): RSocketMagixEndpoint<T> {
val client = HttpClient { val client = HttpClient {
install(WebSockets) install(WebSockets)
install(RSocketSupport) { install(RSocketSupport) {
@ -73,7 +72,7 @@ public class RSocketMagixEndpoint(
client.close() client.close()
} }
return RSocketMagixEndpoint(coroutineContext, rSocket) return RSocketMagixEndpoint(coroutineContext, payloadSerializer, rSocket)
} }
} }
} }

View File

@ -3,25 +3,25 @@ package space.kscience.dataforge.magix.service
import io.ktor.network.selector.ActorSelectorManager import io.ktor.network.selector.ActorSelectorManager
import io.ktor.network.sockets.SocketOptions import io.ktor.network.sockets.SocketOptions
import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.aSocket
import io.ktor.util.KtorExperimentalAPI
import io.rsocket.kotlin.core.RSocketConnectorBuilder import io.rsocket.kotlin.core.RSocketConnectorBuilder
import io.rsocket.kotlin.transport.ktor.clientTransport import io.rsocket.kotlin.transport.ktor.clientTransport
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.KSerializer
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
/** /**
* Create a plain TCP based [RSocketMagixEndpoint] * Create a plain TCP based [RSocketMagixEndpoint]
*/ */
@OptIn(KtorExperimentalAPI::class) public suspend fun <T> RSocketMagixEndpoint.Companion.withTcp(
public suspend fun RSocketMagixEndpoint.Companion.withTcp(
host: String, host: String,
port: Int, port: Int,
payloadSerializer: KSerializer<T>,
tcpConfig: SocketOptions.TCPClientSocketOptions.() -> Unit = {}, tcpConfig: SocketOptions.TCPClientSocketOptions.() -> Unit = {},
rSocketConfig: RSocketConnectorBuilder.ConnectionConfigBuilder.() -> Unit = {}, rSocketConfig: RSocketConnectorBuilder.ConnectionConfigBuilder.() -> Unit = {},
): RSocketMagixEndpoint { ): RSocketMagixEndpoint<T> {
val transport = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().clientTransport(host, port, tcpConfig) val transport = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().clientTransport(host, port, tcpConfig)
val rSocket = buildConnector(rSocketConfig).connect(transport) val rSocket = buildConnector(rSocketConfig).connect(transport)
return RSocketMagixEndpoint(coroutineContext, rSocket) return RSocketMagixEndpoint(coroutineContext, payloadSerializer, rSocket)
} }

View File

@ -1,9 +1,9 @@
rootProject.name = "controls.kt"
pluginManagement { pluginManagement {
val kotlinVersion = "1.5.0-M2" val toolsVersion = "0.10.0"
val toolsVersion = "0.9.5-dev"
repositories { repositories {
mavenLocal()
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
@ -14,15 +14,9 @@ pluginManagement {
id("ru.mipt.npm.gradle.mpp") version toolsVersion id("ru.mipt.npm.gradle.mpp") version toolsVersion
id("ru.mipt.npm.gradle.jvm") version toolsVersion id("ru.mipt.npm.gradle.jvm") version toolsVersion
id("ru.mipt.npm.gradle.js") version toolsVersion id("ru.mipt.npm.gradle.js") version toolsVersion
id("ru.mipt.npm.gradle.publish") version toolsVersion
kotlin("jvm") version kotlinVersion
kotlin("js") version kotlinVersion
kotlin("multiplatform") version kotlinVersion
} }
} }
rootProject.name = "controls.kt"
include( include(
":controls-core", ":controls-core",
":controls-tcp", ":controls-tcp",
@ -35,7 +29,6 @@ include(
":magix:magix-service", ":magix:magix-service",
":magix:magix-java-client", ":magix:magix-java-client",
":controls-magix-client", ":controls-magix-client",
":controls-magix-server",
":motors" ":motors"
) )