-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* support for multiplexed transport * simpler limiter implementation
- Loading branch information
Showing
53 changed files
with
2,169 additions
and
1,487 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/RSocketProtocolVersion.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright 2015-2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.rsocket.kotlin | ||
|
||
// TODO: Make public, deciding on naming, drop Version in frame.io | ||
internal data class RSocketProtocolVersion( | ||
val major: Int, | ||
val minor: Int, | ||
) : Comparable<RSocketProtocolVersion> { | ||
|
||
init { | ||
check(major >= 0) { "Major version component should be non-negative but was $major" } | ||
check(minor >= 0) { "Minor version component should be non-negative: but was $minor" } | ||
} | ||
|
||
override fun compareTo(other: RSocketProtocolVersion): Int { | ||
return when (val majorResult = major.compareTo(other.major)) { | ||
0 -> minor.compareTo(other.minor) | ||
else -> majorResult | ||
} | ||
} | ||
|
||
override fun toString(): String = "$major.$minor" | ||
|
||
companion object { | ||
val V1: RSocketProtocolVersion = RSocketProtocolVersion(1, 0) | ||
val V2: RSocketProtocolVersion = RSocketProtocolVersion(2, 0) | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
...core/src/commonMain/kotlin/io/rsocket/kotlin/connection/ConnectionEstablishmentContext.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright 2015-2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.rsocket.kotlin.connection | ||
|
||
import io.ktor.utils.io.core.* | ||
import io.rsocket.kotlin.* | ||
import io.rsocket.kotlin.frame.* | ||
import io.rsocket.kotlin.frame.io.* | ||
import io.rsocket.kotlin.internal.io.* | ||
import io.rsocket.kotlin.keepalive.* | ||
import io.rsocket.kotlin.payload.* | ||
|
||
// send/receive setup, resume, resume ok, lease, error | ||
internal interface ConnectionEstablishmentContext { | ||
// only setup|lease|resume|resume_ok|error frames | ||
suspend fun receiveFrame(): Frame | ||
|
||
suspend fun sendSetup( | ||
version: Version, | ||
honorLease: Boolean, | ||
keepAlive: KeepAlive, | ||
resumeToken: ByteReadPacket?, | ||
payloadMimeType: PayloadMimeType, | ||
payload: Payload, | ||
) | ||
} | ||
|
||
internal interface ConnectionEstablishmentHandler { | ||
val isClient: Boolean | ||
suspend fun establishConnection(context: ConnectionEstablishmentContext): ConnectionConfig | ||
} | ||
|
||
internal abstract class AbstractConnectionEstablishmentContext( | ||
private val bufferPool: BufferPool, | ||
) : ConnectionEstablishmentContext { | ||
protected abstract suspend fun sendFrame(frame: ByteReadPacket) | ||
protected abstract suspend fun receiveFrameRaw(): ByteReadPacket | ||
private suspend fun sendFrame(frame: Frame): Unit = sendFrame(frame.toPacket(bufferPool)) | ||
override suspend fun receiveFrame(): Frame = receiveFrameRaw().readFrame(bufferPool) | ||
|
||
override suspend fun sendSetup( | ||
version: Version, | ||
honorLease: Boolean, | ||
keepAlive: KeepAlive, | ||
resumeToken: ByteReadPacket?, | ||
payloadMimeType: PayloadMimeType, | ||
payload: Payload, | ||
): Unit = sendFrame(SetupFrame(version, honorLease, keepAlive, resumeToken, payloadMimeType, payload)) | ||
} |
67 changes: 67 additions & 0 deletions
67
rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/connection/ConnectionInbound.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright 2015-2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.rsocket.kotlin.connection | ||
|
||
import io.ktor.utils.io.core.* | ||
import io.rsocket.kotlin.* | ||
import io.rsocket.kotlin.frame.* | ||
import io.rsocket.kotlin.internal.* | ||
import kotlinx.coroutines.* | ||
|
||
internal interface ConnectionInbound { | ||
fun receiveMetadataPush(metadata: ByteReadPacket) | ||
fun receiveKeepAlive(respond: Boolean, data: ByteReadPacket, lastPosition: Long) | ||
fun receiveLease(ttl: Int, numberOfRequests: Int, metadata: ByteReadPacket?) | ||
fun receiveError(cause: Throwable) | ||
} | ||
|
||
internal class ConnectionFrameHandler(private val inbound: ConnectionInbound) { | ||
fun handleFrame(frame: Frame): Unit = when (frame) { | ||
is MetadataPushFrame -> inbound.receiveMetadataPush(frame.metadata) | ||
is KeepAliveFrame -> inbound.receiveKeepAlive(frame.respond, frame.data, frame.lastPosition) | ||
is ErrorFrame -> inbound.receiveError(frame.throwable) | ||
is LeaseFrame -> inbound.receiveLease(frame.ttl, frame.numberOfRequests, frame.metadata) | ||
// ignore other frames | ||
else -> frame.close() | ||
} | ||
} | ||
|
||
internal class ConnectionInboundImpl( | ||
private val sessionScope: CoroutineScope, | ||
private val requestsScope: CoroutineScope, | ||
private val responder: RSocket, | ||
private val keepAliveHandler: KeepAliveHandler, | ||
) : ConnectionInbound { | ||
override fun receiveMetadataPush(metadata: ByteReadPacket) { | ||
requestsScope.launch { | ||
metadata.use { responder.metadataPush(it) } | ||
} | ||
} | ||
|
||
override fun receiveKeepAlive(respond: Boolean, data: ByteReadPacket, lastPosition: Long) { | ||
keepAliveHandler.receive(data, respond) | ||
} | ||
|
||
override fun receiveLease(ttl: Int, numberOfRequests: Int, metadata: ByteReadPacket?) { | ||
metadata?.close() | ||
sessionScope.cancel("Lease is not supported") | ||
} | ||
|
||
override fun receiveError(cause: Throwable) { | ||
sessionScope.cancel("Session received an error", cause) | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
rsocket-core/src/commonMain/kotlin/io/rsocket/kotlin/connection/ConnectionOutbound.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Copyright 2015-2024 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.rsocket.kotlin.connection | ||
|
||
import io.ktor.utils.io.core.* | ||
import io.rsocket.kotlin.frame.* | ||
import io.rsocket.kotlin.internal.io.* | ||
|
||
internal interface ConnectionOutbound { | ||
suspend fun sendMetadataPush(metadata: ByteReadPacket) | ||
suspend fun sendKeepAlive(respond: Boolean, data: ByteReadPacket, lastPosition: Long) | ||
suspend fun sendError(cause: Throwable) | ||
} | ||
|
||
internal abstract class AbstractConnectionOutbound( | ||
private val bufferPool: BufferPool, | ||
) : ConnectionOutbound { | ||
protected abstract suspend fun sendFrame(frame: ByteReadPacket) | ||
private suspend fun sendFrame(frame: Frame): Unit = sendFrame(frame.toPacket(bufferPool)) | ||
|
||
override suspend fun sendError(cause: Throwable) { | ||
sendFrame(ErrorFrame(0, cause)) | ||
} | ||
|
||
override suspend fun sendMetadataPush(metadata: ByteReadPacket) { | ||
sendFrame(MetadataPushFrame(metadata)) | ||
} | ||
|
||
override suspend fun sendKeepAlive(respond: Boolean, data: ByteReadPacket, lastPosition: Long) { | ||
sendFrame(KeepAliveFrame(respond, lastPosition, data)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.