websocket client now includes transport device to use in higher order protocols

This commit is contained in:
Sergey Chernov 2024-11-23 11:47:56 +07:00
parent 4098358233
commit 9545ca28cf
2 changed files with 80 additions and 68 deletions

View File

@ -8,7 +8,7 @@ plugins {
}
group = "net.sergeych"
version = "0.4.5-SNAPSHOT"
version = "0.4.6-SNAPSHOT"
repositories {
mavenCentral()

View File

@ -11,10 +11,7 @@ import kotlinx.coroutines.channels.ClosedReceiveChannelException
import kotlinx.coroutines.channels.ClosedSendChannelException
import kotlinx.coroutines.launch
import net.sergeych.crypto2.SigningKey
import net.sergeych.kiloparsec.KiloClient
import net.sergeych.kiloparsec.KiloConnectionData
import net.sergeych.kiloparsec.KiloInterface
import net.sergeych.kiloparsec.RemoteInterface
import net.sergeych.kiloparsec.*
import net.sergeych.mp_logger.LogTag
import net.sergeych.mp_logger.exception
import net.sergeych.mp_logger.info
@ -24,23 +21,39 @@ import net.sergeych.tools.AtomicCounter
private val counter = AtomicCounter()
/**
* Shortcut to create websocket client. Use [webSocketTransportDevice] with [KiloClient]
* for fine-grained control.
*/
fun <S> websocketClient(
path: String,
clientInterface: KiloInterface<S> = KiloInterface(),
client: HttpClient = HttpClient { install(WebSockets) },
secretKey: SigningKey? = null,
sessionMaker: () -> S = {
@Suppress("UNCHECKED_CAST")
Unit as S
},
): KiloClient<S> {
return KiloClient(clientInterface, secretKey) {
KiloConnectionData(webSocketTransportDevice(path), sessionMaker())
}
}
/**
* Create kilopaarsec transport over websocket (ws or wss).
* @param path websocket path (must start with ws:// or wss:// and contain a path part)
* @client use default [HttpClient], it installs [WebSockets] plugin
*/
fun webSocketTransportDevice(
path: String,
client: HttpClient = HttpClient { install(WebSockets) },
): Transport.Device {
var u = Url(path)
if (u.encodedPath.length <= 1)
u = URLBuilder(u).apply {
encodedPath = "/kp"
}.build()
return KiloClient(clientInterface, secretKey) {
val input = Channel<UByteArray>()
val output = Channel<UByteArray>()
val closeHandle = CompletableDeferred<Boolean>()
@ -66,9 +79,8 @@ fun <S> websocketClient(
if (closeHandle.isActive) closeHandle.complete(true)
} catch (_: ClosedSendChannelException) {
log.info { "send channel closed" }
}
catch(_: CancellationException) {}
catch(t: Throwable) {
} catch (_: CancellationException) {
} catch (t: Throwable) {
log.info { "unexpected exception in websock sender: ${t.stackTraceToString()}" }
closeHandle.completeExceptionally(t)
}
@ -109,6 +121,6 @@ fun <S> websocketClient(
closeHandle.complete(true)
// job.cancel()
}
KiloConnectionData(device, sessionMaker())
}
return device
}