Skip to content

Commit 384b442

Browse files
committed
RSocket 예제 추가 중
1 parent 01df9fd commit 384b442

File tree

19 files changed

+274
-12
lines changed

19 files changed

+274
-12
lines changed

build.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ plugins {
2727
id(BuildPlugins.detekt) version BuildPlugins.Versions.detekt apply false
2828
id(BuildPlugins.dokka) version BuildPlugins.Versions.dokka apply false
2929
id(BuildPlugins.dependency_management) version BuildPlugins.Versions.dependency_management
30+
id(BuildPlugins.spring_boot) version BuildPlugins.Versions.spring_boot apply false
3031
`maven-publish`
3132
}
3233

@@ -137,6 +138,7 @@ subprojects {
137138
dependencyManagement {
138139
imports {
139140
mavenBom("org.springframework.boot:spring-boot-dependencies:${Versions.spring_boot}")
141+
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${Versions.spring_cloud}")
140142
}
141143
dependencies {
142144
dependency(Libraries.kotlin_stdlib)

buildSrc/src/main/kotlin/Libraries.kt

+6-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ object BuildPlugins {
88
const val protobuf = "0.8.13"
99
const val avro = "0.17.0"
1010
const val jarTest = "1.0.1"
11-
const val spring_boot = "2.3.4.RELEASE"
11+
const val spring_boot = "2.4.0"
1212
}
1313

1414
const val detekt = "io.gitlab.arturbosch.detekt"
@@ -29,11 +29,12 @@ object BuildPlugins {
2929

3030
object Versions {
3131

32-
const val kotlin = "1.4.10"
33-
const val kotlinx_coroutines = "1.3.9"
32+
const val kotlin = "1.4.20"
33+
const val kotlinx_coroutines = "1.4.1"
3434
const val atomicfu = "0.14.4"
3535

3636
const val spring_boot = BuildPlugins.Versions.spring_boot
37+
const val spring_cloud = "Hoxton.SR9"
3738
const val resilience4j = "1.6.1"
3839
const val vavr = "0.10.0"
3940
const val netty = "4.1.52.Final"
@@ -47,7 +48,7 @@ object Versions {
4748

4849
const val jasync_sql = "1.0.6"
4950

50-
const val reactor = "3.2.12.RELEASE"
51+
const val reactor = "3.4.0"
5152
const val jackson = "2.11.3"
5253

5354
const val mongo_driver = "3.11.0"
@@ -245,7 +246,7 @@ object Libraries {
245246
// Reactor
246247
const val reactor_core = "io.projectreactor:reactor-core:${Versions.reactor}"
247248
const val reactor_test = "io.projectreactor:reactor-test:${Versions.reactor}"
248-
const val reactor_netty = "io.projectreactor.netty:reactor-netty:0.8.11.RELEASE"
249+
const val reactor_netty = "io.projectreactor.netty:reactor-netty:1.0.1"
249250

250251
// RxJava2
251252
const val rxjava2 = "io.reactivex.rxjava2:rxjava:2.2.10"

gradle.properties

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ org.gradle.daemon = true
2020
org.gradle.parallel = true
2121
org.gradle.caching = true
2222

23+
org.gradle.jvmargs = -Xmx4G
24+
2325
kotlin.incremental = true
2426
kotlin.parallel.tasks.in.project = true
2527
kapt.use.worker.api = true
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath = wrapper/dists
3-
distributionUrl = https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
3+
distributionUrl = https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
44
zipStoreBase = GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dependencies {
2+
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.github.debop.rsocket.api
2+
3+
import java.time.Instant
4+
5+
/**
6+
* Message
7+
*
8+
* @author debop
9+
* @since 2020/11/25
10+
*/
11+
data class Message @JvmOverloads constructor(
12+
var origin: String = "",
13+
var interaction: String = "",
14+
var index: Long = 0,
15+
) {
16+
val created = Instant.now().epochSecond
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
plugins {
2+
kotlin("plugin.spring")
3+
id(BuildPlugins.spring_boot)
4+
}
5+
6+
dependencies {
7+
8+
api(project(":rsocket:rsocket-communication:api"))
9+
10+
api(Libraries.kotlinx_coroutines_jdk8)
11+
api(Libraries.kotlinx_coroutines_reactor)
12+
13+
api("org.springframework.boot:spring-boot-starter-rsocket")
14+
15+
testApi("org.springframework.boot:spring-boot-starter-test") {
16+
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
17+
}
18+
testApi(Libraries.reactor_test)
19+
20+
// 이건 Deprecated 된 것입니다. 다른 걸 쓰시길 바랍니다.
21+
api("org.springframework.shell:spring-shell-starter:2.0.1.RELEASE")
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
plugins {
2+
kotlin("plugin.spring")
3+
id(BuildPlugins.spring_boot)
4+
}
5+
6+
dependencies {
7+
8+
api(project(":rsocket:rsocket-communication:api"))
9+
10+
api(Libraries.kotlinx_coroutines_jdk8)
11+
api(Libraries.kotlinx_coroutines_reactor)
12+
13+
api(Libraries.reactor_core)
14+
api(Libraries.reactor_netty)
15+
16+
api("org.springframework.boot:spring-boot-autoconfigure")
17+
api("org.springframework.boot:spring-boot-starter-rsocket")
18+
api("org.springframework.boot:spring-boot-starter-webflux")
19+
20+
testApi("org.springframework.boot:spring-boot-starter-test") {
21+
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
22+
}
23+
testApi(Libraries.reactor_test)
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.github.debop.rsocket.server
2+
3+
import io.github.debop.rsocket.api.Message
4+
import mu.KLogging
5+
import org.springframework.messaging.handler.annotation.MessageMapping
6+
import org.springframework.messaging.rsocket.RSocketRequester
7+
import org.springframework.stereotype.Controller
8+
import javax.annotation.PreDestroy
9+
10+
@Controller
11+
class RSocketController {
12+
13+
companion object: KLogging() {
14+
15+
private const val SERVER = "Server"
16+
private const val RESPONSE = "Response"
17+
private const val STREAM = "Stream"
18+
private const val CHANNEL = "Channel"
19+
}
20+
21+
private val clients = mutableListOf<RSocketRequester>()
22+
23+
@PreDestroy
24+
fun shutdown() {
25+
logger.info { "Detaching all remaining clients ..." }
26+
clients.forEach { requester ->
27+
runCatching { requester.rsocket()?.dispose() }
28+
}
29+
logger.info { "Shutting down." }
30+
}
31+
32+
@MessageMapping("request-response")
33+
suspend fun requestResponse(request: Message): Message {
34+
logger.debug { "Received request-response request: $request" }
35+
return Message(SERVER, RESPONSE)
36+
}
37+
38+
@MessageMapping("fire-and-forget")
39+
suspend fun fireAndForget(request: Message) {
40+
logger.debug { "Received fire-and-forget request: $request" }
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.github.debop.rsocket.server
2+
3+
import org.springframework.boot.WebApplicationType
4+
import org.springframework.boot.autoconfigure.SpringBootApplication
5+
import org.springframework.boot.runApplication
6+
7+
8+
@SpringBootApplication
9+
class RSocketServerApplication
10+
11+
fun main(vararg args: String) {
12+
runApplication<RSocketServerApplication>(*args) {
13+
webApplicationType = WebApplicationType.REACTIVE
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.github.debop.rsocket.server
2+
3+
import io.rsocket.core.RSocketServer
4+
import io.rsocket.core.Resume
5+
import org.springframework.boot.rsocket.server.RSocketServerCustomizer
6+
import org.springframework.context.annotation.Profile
7+
import org.springframework.stereotype.Component
8+
9+
/**
10+
* Make the socket capable of resumption.
11+
* By default, the Resume Session will have a duration of 120s, a timeout of
12+
* 10s, and use the In Memory (volatile, non-persistent) session store.
13+
*/
14+
@Profile("resumption")
15+
@Component
16+
class RSocketServerResumptionConfig: RSocketServerCustomizer {
17+
/**
18+
* Callback to customize a [RSocketServer] instance.
19+
* @param rSocketServer the RSocket server to customize
20+
*/
21+
override fun customize(rSocketServer: RSocketServer) {
22+
rSocketServer.resume(Resume())
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
spring:
2+
main:
3+
lazy-initialization: true
4+
5+
rsocket:
6+
server:
7+
port: 7000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.github.debop.rsocket.server
2+
3+
import io.github.debop.rsocket.api.Message
4+
import kotlinx.coroutines.delay
5+
import kotlinx.coroutines.flow.Flow
6+
import kotlinx.coroutines.flow.flow
7+
import kotlinx.coroutines.runBlocking
8+
import mu.KLogging
9+
import org.junit.jupiter.api.Test
10+
import org.springframework.beans.factory.annotation.Autowired
11+
import org.springframework.boot.rsocket.context.LocalRSocketServerPort
12+
import org.springframework.boot.test.context.SpringBootTest
13+
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
14+
import org.springframework.messaging.handler.annotation.MessageMapping
15+
import org.springframework.messaging.rsocket.RSocketRequester
16+
import org.springframework.messaging.rsocket.RSocketStrategies
17+
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler
18+
import org.springframework.messaging.rsocket.connectTcpAndAwait
19+
import org.springframework.messaging.rsocket.retrieveMono
20+
import java.util.UUID
21+
22+
23+
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
24+
class RSocketServerApplicationTest(
25+
@Autowired private val builder: RSocketRequester.Builder,
26+
@Autowired private val strategies: RSocketStrategies,
27+
@LocalRSocketServerPort private val port: Int,
28+
) {
29+
30+
val responder = RSocketMessageHandler.responder(strategies, ClientHandler())
31+
32+
val requester = runBlocking {
33+
builder
34+
.setupRoute("shell-client")
35+
.setupData(UUID.randomUUID().toString())
36+
.rsocketConnector { it.acceptor(responder) }
37+
.connectTcpAndAwait("localhost", port)
38+
}
39+
40+
@Test
41+
fun `fire and forget`() = runBlocking<Unit> {
42+
val result = requester.route("fire-and-forget")
43+
.data(Message("TEST", "Fire-And-Forget"))
44+
.retrieveMono<Void>()
45+
}
46+
47+
class ClientHandler {
48+
49+
companion object: KLogging()
50+
51+
@MessageMapping("client-status")
52+
fun statusUpdate(status: String): Flow<String> {
53+
logger.info { "Connection: $status" }
54+
return flow {
55+
delay(5000)
56+
emit(Runtime.getRuntime().freeMemory().toString())
57+
}
58+
}
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#
2+
# Copyright (c) 2016. Sunghyouk Bae <[email protected]>
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
junit.jupiter.testinstance.lifecycle.default = per_class
17+
18+
junit.jupiter.execution.parallel.enabled = true
19+
junit.jupiter.execution.parallel.mode.default = concurrent
20+
junit.jupiter.execution.parallel.config.strategy = dynamic
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<configuration>
3+
<!-- help : http://logback.qos.ch/manual/appenders.html -->
4+
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
5+
<withJansi>true</withJansi>
6+
<immediateFlush>true</immediateFlush>
7+
<encoder>
8+
<pattern>%d{HH:mm:ss.SSS} %5level [%24.24thread] %40.40logger{39}:%4line: %msg%n</pattern>
9+
<charset>UTF-8</charset>
10+
</encoder>
11+
</appender>
12+
13+
<logger name="io.github.debop" level="DEBUG"/>
14+
15+
<root level="INFO">
16+
<appender-ref ref="console"/>
17+
</root>
18+
19+
</configuration>

settings.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ include("jackson:dataformats-binary")
2626
include("jackson:dataformats-text")
2727
include("jackson:module-examples")
2828

29+
include("rsocket:rsocket-communication:api")
30+
include("rsocket:rsocket-communication:client")
31+
include("rsocket:rsocket-communication:server")
32+
2933
include("spring-boot:basic")
3034
include("spring-boot:cache2k")
3135
include("spring-boot:cache2k-jcache")

spring-boot/route/build.gradle.kts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import org.springframework.boot.gradle.tasks.bundling.BootJar
1+
// import org.springframework.boot.gradle.tasks.bundling.BootJar
22

33
plugins {
44
kotlin("plugin.spring")
55
kotlin("plugin.noarg")
66

7-
id(BuildPlugins.spring_boot) version BuildPlugins.Versions.spring_boot
7+
id(BuildPlugins.spring_boot)
88
}
99

10-
val bootJar: BootJar by tasks
11-
bootJar.enabled = false
10+
// val bootJar: BootJar by tasks
11+
// bootJar.enabled = false
1212

1313
dependencies {
1414

spring-boot/webflux/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
kotlin("plugin.spring")
55
kotlin("plugin.noarg")
66

7-
id(BuildPlugins.spring_boot) version BuildPlugins.Versions.spring_boot
7+
id(BuildPlugins.spring_boot)
88
}
99

1010
val bootJar: BootJar by tasks

spring-boot/webmvc/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
kotlin("plugin.spring")
55
kotlin("plugin.noarg")
66

7-
id(BuildPlugins.spring_boot) version BuildPlugins.Versions.spring_boot
7+
id(BuildPlugins.spring_boot)
88
}
99

1010
val bootJar: BootJar by tasks

0 commit comments

Comments
 (0)