Skip to content

Commit 35b3478

Browse files
olme04whyoleg
authored andcommitted
Update readme for 0.15.0
1 parent 58ca797 commit 35b3478

File tree

1 file changed

+141
-77
lines changed

1 file changed

+141
-77
lines changed

README.md

Lines changed: 141 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,99 @@
11
# rsocket-kotlin
22

3-
RSocket Kotlin multi-platform implementation based on [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines).
3+
RSocket Kotlin multi-platform implementation based on
4+
[kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) and [ktor-io](https://github.com/ktorio/ktor).
45

5-
RSocket is a binary protocol for use on byte stream transports such as TCP, WebSockets and Aeron.
6+
RSocket is a binary application protocol providing Reactive Streams semantics for use on byte stream transports such as
7+
TCP, WebSockets, QUIC and Aeron.
68

79
It enables the following symmetric interaction models via async message passing over a single connection:
810

9-
- request/response (stream of 1)
10-
- request/stream (finite stream of many)
11-
- fire-and-forget (no response)
12-
- event subscription (infinite stream of many)
11+
* [Fire-and-Forget](https://rsocket.io/about/motivations#fire-and-forget)
12+
* [Request-Response](https://rsocket.io/about/motivations#requestresponse-single-response)
13+
* [Request-Stream](https://rsocket.io/about/motivations#requeststream-multi-response-finite)
14+
* [Request-Channel](https://rsocket.io/about/motivations#channel)
1315

1416
Learn more at http://rsocket.io
1517

1618
## Supported platforms and transports :
1719

18-
Transports are implemented based on [ktor](https://github.com/ktorio/ktor) to ensure Kotlin multiplatform. So it depends on `ktor` engines
19-
for available transports and platforms (JVM, JS, Native):
20+
Local (in memory) transport is supported on all targets.
21+
Most of other transports are implemented using [ktor](https://github.com/ktorio/ktor) to ensure Kotlin multiplatform.
22+
So it depends on `ktor` client/server engines for available transports and platforms.
2023

21-
* JVM - TCP and WebSocket for both client and server
22-
* JS - WebSocket client only
23-
* Native - TCP (linux x64, macos, ios, watchos, tvos) for both client and server
24+
### Client transports:
2425

25-
## Interactions
26+
| | TCP | WebSocket |
27+
|-----------------------------|-----------------------------------------|------------|
28+
| JVM | ✅ via ktor | ✅ via ktor |
29+
| JS | ✅ via nodeJS (not supported in browser) | ✅ via ktor |
30+
| Native<br/>(except windows) | ✅ via ktor | ✅ via ktor |
2631

27-
RSocket interface contains 5 methods:
32+
### Server transports:
2833

29-
* Fire and Forget:
30-
31-
`suspend fun fireAndForget(payload: Payload)`
32-
* Request-Response:
33-
34-
`suspend requestResponse(payload: Payload): Payload`
35-
* Request-Stream:
36-
37-
`fun requestStream(payload: Payload): Flow<Payload>`
38-
* Request-Channel:
39-
40-
`fun requestChannel(initPayload: Payload, payloads: Flow<Payload>): Flow<Payload>`
41-
* Metadata-Push:
42-
43-
`suspend fun metadataPush(metadata: ByteReadPacket)`
34+
| | TCP | WebSocket |
35+
|-----------------------------|-----------------------------------------|------------|
36+
| JVM | ✅ via ktor | ✅ via ktor |
37+
| JS | ✅ via nodeJS (not supported in browser) ||
38+
| Native<br/>(except windows) | ✅ via ktor | ✅ via ktor |
4439

4540
## Using in your projects
4641

47-
Make sure, that you use Kotlin 1.6.10
42+
rsocket-kotlin is available on [Maven Central](https://mvnrepository.com/artifact/io.rsocket.kotlin)
4843

49-
### Gradle:
44+
Make sure, that you use Kotlin 1.6.20+, ktor 2.0.0+ and have `mavenCentral()` in the list of repositories:
5045

5146
```kotlin
5247
repositories {
5348
mavenCentral()
5449
}
55-
dependencies {
56-
implementation("io.rsocket.kotlin:rsocket-core:0.14.3")
57-
58-
// TCP ktor transport
59-
implementation("io.rsocket.kotlin:rsocket-transport-ktor:0.14.3")
50+
```
6051

61-
// WS ktor transport client plugin
62-
implementation("io.rsocket.kotlin:rsocket-transport-ktor-client:0.14.3")
52+
### Ktor plugins
6353

64-
// WS ktor transport server plugin
65-
implementation("io.rsocket.kotlin:rsocket-transport-ktor-server:0.14.3")
66-
}
67-
```
54+
rsocket-kotlin provides [client](https://ktor.io/docs/http-client-plugins.html)
55+
and [server](https://ktor.io/docs/plugins.html) plugins for [ktor](https://ktor.io)
6856

69-
For WS ktor transport, available client or server engine should be added:
57+
Dependencies:
7058

7159
```kotlin
7260
dependencies {
73-
// client engines for WS transport
74-
implementation("io.ktor:ktor-client-js:1.6.7") //js
75-
implementation("io.ktor:ktor-client-cio:1.6.7") //jvm
76-
implementation("io.ktor:ktor-client-okhttp:1.6.7") //jvm
77-
78-
// server engines for WS transport (jvm only)
79-
implementation("io.ktor:ktor-server-cio:1.6.7")
80-
implementation("io.ktor:ktor-server-netty:1.6.7")
81-
implementation("io.ktor:ktor-server-jetty:1.6.7")
82-
implementation("io.ktor:ktor-server-tomcat:1.6.7")
61+
//for client
62+
implementation("io.rsocket.kotlin:rsocket-ktor-client:0.15.0")
63+
64+
//for server
65+
implementation("io.rsocket.kotlin:rsocket-ktor-server:0.15.0")
8366
}
8467
```
8568

86-
## Usage
87-
88-
### Client WebSocket with CIO ktor engine
69+
Example of client plugin usage:
8970

9071
```kotlin
9172
//create ktor client
92-
val client = HttpClient(CIO) {
93-
install(WebSockets)
73+
val client = HttpClient {
74+
install(WebSockets) //rsocket requires websockets plugin installed
9475
install(RSocketSupport) {
95-
connector = RSocketConnector {
96-
//configure rSocket connector (all values have defaults)
76+
//configure rSocket connector (all values have defaults)
77+
connector {
78+
maxFragmentSize = 1024
79+
9780
connectionConfig {
9881
keepAlive = KeepAlive(
9982
interval = 30.seconds,
10083
maxLifetime = 2.minutes
10184
)
10285

10386
//payload for setup frame
104-
setupPayload { buildPayload { data("hello world") } }
87+
setupPayload {
88+
buildPayload {
89+
data("""{ "data": "setup" }""")
90+
}
91+
}
10592

10693
//mime types
10794
payloadMimeType = PayloadMimeType(
108-
data = "application/json",
109-
metadata = "application/json"
95+
data = WellKnownMimeType.ApplicationJson,
96+
metadata = WellKnownMimeType.MessageRSocketCompositeMetadata
11097
)
11198
}
11299

@@ -124,22 +111,30 @@ val client = HttpClient(CIO) {
124111
val rSocket: RSocket = client.rSocket("wss://demo.rsocket.io/rsocket")
125112

126113
//request stream
127-
val stream: Flow<Payload> = rSocket.requestStream(Payload.Empty)
114+
val stream: Flow<Payload> = rSocket.requestStream(
115+
buildPayload {
116+
data("""{ "data": "hello world" }""")
117+
}
118+
)
128119

129120
//take 5 values and print response
130121
stream.take(5).collect { payload: Payload ->
131122
println(payload.data.readText())
132123
}
133124
```
134125

135-
### Server WebSocket with CIO ktor engine
126+
Example of server plugin usage:
136127

137128
```kotlin
138129
//create ktor server
139130
embeddedServer(CIO) {
131+
install(WebSockets) //rsocket requires websockets plugin installed
140132
install(RSocketSupport) {
141133
//configure rSocket server (all values have defaults)
142-
server = RSocketServer {
134+
135+
server {
136+
maxFragmentSize = 1024
137+
143138
//install interceptors
144139
interceptors {
145140
forConnection(::SomeConnectionInterceptor)
@@ -148,23 +143,29 @@ embeddedServer(CIO) {
148143
}
149144
//configure routing
150145
routing {
151-
//configure route `url:port/rsocket`
146+
//configure route `/rsocket`
152147
rSocket("rsocket") {
148+
println(config.setupPayload.data.readText()) //print setup payload data
149+
153150
RSocketRequestHandler {
154151
//handler for request/response
155152
requestResponse { request: Payload ->
156-
//... some work here
153+
println(request.data.readText()) //print request payload data
157154
delay(500) // work emulation
158155
buildPayload {
159-
data("data")
160-
metadata("metadata")
156+
data("""{ "data": "Server response" }""")
161157
}
162158
}
163159
//handler for request/stream
164160
requestStream { request: Payload ->
161+
println(request.data.readText()) //print request payload data
165162
flow {
166-
repeat(1000) { i ->
167-
emit(buildPayload { data("data: $i") })
163+
repeat(10) { i ->
164+
emit(
165+
buildPayload {
166+
data("""{ "data": "Server stream response: $i" }""")
167+
}
168+
)
168169
}
169170
}
170171
}
@@ -174,10 +175,72 @@ embeddedServer(CIO) {
174175
}.start(true)
175176
```
176177

178+
### Standalone transports
179+
180+
rsocket-kotlin also provides standalone transports which can be used to establish RSocket connection:
181+
182+
Dependencies:
183+
184+
```kotlin
185+
dependencies {
186+
implementation("io.rsocket.kotlin:rsocket-core:0.15.0")
187+
188+
// TCP ktor client/server transport
189+
implementation("io.rsocket.kotlin:rsocket-transport-ktor-tcp:0.15.0")
190+
191+
// WS ktor client transport
192+
implementation("io.rsocket.kotlin:rsocket-transport-ktor-websocket-client:0.15.0")
193+
194+
// WS ktor server transport
195+
implementation("io.rsocket.kotlin:rsocket-transport-ktor-websocket-server:0.15.0")
196+
197+
// TCP nodeJS client/server transport
198+
implementation("io.rsocket.kotlin:rsocket-transport-nodejs-tcp:0.15.0")
199+
}
200+
```
201+
202+
Example of usage standalone client transport:
203+
204+
```kotlin
205+
206+
val transport = TcpClientTransport("0.0.0.0", 8080)
207+
val connector = RSocketConnector {
208+
//configuration goes here
209+
}
210+
val rsocket: RSocket = connector.connect(transport)
211+
//use rsocket to do request
212+
val response = rsocket.requestResponse(buildPayload { data("""{ "data": "hello world" }""") })
213+
println(response.data.readText())
214+
```
215+
216+
Example of usage standalone server transport:
217+
218+
```kotlin
219+
220+
val transport = TcpServerTransport("0.0.0.0", 8080)
221+
val connector = RSocketServer {
222+
//configuration goes here
223+
}
224+
val server: TcpServer = server.bind(transport) {
225+
RSocketRequestHandler {
226+
//handler for request/response
227+
requestResponse { request: Payload ->
228+
println(request.data.readText()) //print request payload data
229+
delay(500) // work emulation
230+
buildPayload {
231+
data("""{ "data": "Server response" }""")
232+
}
233+
}
234+
}
235+
}
236+
server.handlerJob.join() //wait for server to finish
237+
```
238+
177239
### More samples:
178240

179-
- [multiplatform-chat](samples/chat) - chat implementation with JVM server and JS/JVM client with shared classes and
180-
serializing data using [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization)
241+
- [multiplatform-chat](samples/chat) - chat implementation with JVM/JS/Native server and JVM/JS/Native client with
242+
shared classes and shared data serialization
243+
using [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization)
181244

182245
## Reactive Streams Semantics
183246

@@ -187,9 +250,10 @@ From [RSocket protocol](https://github.com/rsocket/rsocket/blob/master/Protocol.
187250
This is a credit-based model where the Requester grants the Responder credit for the number of PAYLOADs it can send.
188251
It is sometimes referred to as "request-n" or "request(n)".
189252

190-
`kotlinx.coroutines` doesn't truly support `request(n)` semantic, but it has flexible `CoroutineContext`
191-
which can be used to achieve something similar. `rsocket-kotlin` contains `RequestStrategy` coroutine context element, which defines,
192-
strategy for sending of `requestN` frames.
253+
`kotlinx.coroutines` doesn't truly support `request(n)` semantic,
254+
but it has flexible `CoroutineContext` which can be used to achieve something similar.
255+
`rsocket-kotlin` contains `RequestStrategy` coroutine context element, which defines,
256+
strategy for sending of `requestN`frames.
193257

194258
Example:
195259

@@ -215,7 +279,7 @@ For bugs, questions and discussions please use the [Github Issues](https://githu
215279

216280
## LICENSE
217281

218-
Copyright 2015-2020 the original author or authors.
282+
Copyright 2015-2022 the original author or authors.
219283

220284
Licensed under the Apache License, Version 2.0 (the "License");
221285
you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)