5.3. Annotated Responders
RSocket ์๋ต์๋ @MessageMapping๊ณผ @ConnectMapping ๋ฉ์๋๋ก ๊ตฌํํ ์ ์๋ค. @MessageMapping ๋ฉ์๋๋ ๊ฐ ์์ฒญ์
์ฒ๋ฆฌํ๊ณ @ConnectMapping ๋ฉ์๋๋ ์ปค๋ฅ์
๋ ๋ฒจ ์ด๋ฒคํธ(์ค์ ๊ณผ ๋ฉํ ๋ฐ์ดํฐ ํธ์)๋ฅผ ์ฒ๋ฆฌํ๋ค. ์ด๋
ธํ
์ด์
๋ฌ๋ฆฐ ์๋ต์(annotated
responder)๋ ์๋ฒ ์ธก์์ ์๋ตํ๊ณ ํด๋ผ์ด์ธํธ ์ธก์์ ์๋ตํ๊ธฐ ์ํด ๋์นญ์ ์ผ๋ก ๋ชจ๋ ์ง์ํ๋ค.
5.3.1. Server Responders
์๋ฒ ์ธก์์ ์ด๋
ธํ
์ด์
๋ฌ๋ฆฐ ์๋ต์(annotated responder)๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด RSocketMessageHandler๋ฅผ ์คํ๋ง ์ค์ ์ ์ถ๊ฐํ์ฌ
@Controller ๋น๊ณผ @MessageMapping ๋ฐ @ConnectMapping ๋ฉ์๋๋ฅผ ๊ฐ์งํ๋๋ก ํ๋ค.
Java:
@Configuration
static class ServerConfig {
@Bean
public RSocketMessageHandler rsocketMessageHandler() {
RSocketMessageHandler handler = new RSocketMessageHandler();
handler.routeMatcher(new PathPatternRouteMatcher());
return handler;
}
}
Kotlin:
@Configuration
class ServerConfig {
@Bean
fun rsocketMessageHandler() = RSocketMessageHandler().apply {
routeMatcher = PathPatternRouteMatcher()
}
}
๋ค์์ผ๋ก ์๋ฐ RSocket API๋ฅผ ํตํด RSocket ์๋ฒ๋ฅผ ์์ํ๊ณ ๋ค์๊ณผ ๊ฐ์ด responder์ ๋ํ RSocketMessageHandler๋ฅผ ์ฐ๊ฒฐํ๋ค:
Java:
ApplicationContext context = ... ;
RSocketMessageHandler handler = context.getBean(RSocketMessageHandler.class);
CloseableChannel server =
RSocketServer.create(handler.responder())
.bind(TcpServerTransport.create("localhost", 7000))
.block();
Kotlin:
import org.springframework.beans.factory.getBean
val context: ApplicationContext = ...
val handler = context.getBean<RSocketMessageHandler>()
val server = RSocketServer.create(handler.responder())
.bind(TcpServerTransport.create("localhost", 7000))
.awaitFirst()
RSocketMessageHandler๋ ๋ฉํ๋ฐ์ดํฐ
composite์ routing์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ๋ค. ๋ค๋ฅธ mime ํ์
์ผ๋ก ๋ฐ๊พธ๊ฑฐ๋ ๋ค๋ฅธ ๋ฉํ ๋ฐ์ดํฐ mime ํ์
์
๋ฑ๋กํ๋ ค๋ฉด
MetadataExtractor์ ์ค์ ํ ์ ์๋ค.
๋ฉํ ๋ฐ์ดํฐ์ ๋ฐ์ดํฐ ํฌ๋งท์ ์ง์ํ๋๋ฐ ํ์ํ Encoder์ Decoder ์ธ์คํด์ค๋ฅผ ์ค์ ํด์ผ ํ๋ค. ์ฝ๋ฑ ๊ตฌํ์ ์ํด์๋ spring-web
๋ชจ๋์ด ํ์ํ ์ ์๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก SimpleRouteMatcher๋ AntPathMatcher๋ฅผ ํตํด ๋ผ์ฐํ
๋งค์นญํ๋๋ฐ ์ฌ์ฉ๋๋ค. ํจ๊ณผ์ ์ธ ๋ผ์ฐํ
๋งค์นญ์ ์ํด spring-web
๋ชจ๋์ PathPatternRouteMatcher๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. RSocket ๋ผ์ฐํ
์ ๊ณ์ธต์ ์ผ ์ ์์ง๋ง URL path๋ ์๋๋ค. ๋ ๋ผ์ฐํ
๋งค์นญ์
๊ธฐ๋ณธ์ ์ผ๋ก โ.โ๋ฅผ ๊ตฌ๋ถ์๋ก ์ฌ์ฉํ๋ฉฐ HTTP URL๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก URL ๋์ฝ๋ฉ์ ์๋ค.
RSocketMessageHandler๋ RSocketStrategies๋ฅผ ํตํด ์ค์ ํ ์ ์์ผ๋ฉฐ, ๋์ผํ ํ๋ก์ธ์ค์์ ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ฌ์ด์ ์ค์ ์
๊ณต์ ํด์ผํ๋ ๊ฒฝ์ฐ ์ ์ฉํ ์ ์๋ค:
Java:
@Configuration
static class ServerConfig {
@Bean
public RSocketMessageHandler rsocketMessageHandler() {
RSocketMessageHandler handler = new RSocketMessageHandler();
handler.setRSocketStrategies(rsocketStrategies());
return handler;
}
@Bean
public RSocketStrategies rsocketStrategies() {
return RSocketStrategies.builder()
.encoders(encoders -> encoders.add(new Jackson2CborEncoder()))
.decoders(decoders -> decoders.add(new Jackson2CborDecoder()))
.routeMatcher(new PathPatternRouteMatcher())
.build();
}
}
Kotlin:
@Configuration
class ServerConfig {
@Bean
fun rsocketMessageHandler() = RSocketMessageHandler().apply {
rSocketStrategies = rsocketStrategies()
}
@Bean
fun rsocketStrategies() = RSocketStrategies.builder()
.encoders { it.add(Jackson2CborEncoder()) }
.decoders { it.add(Jackson2CborDecoder()) }
.routeMatcher(PathPatternRouteMatcher())
.build()
}
5.3.2. Client Responders
ํด๋ผ์ด์ธํธ ์ธก์ ์ด๋
ธํ
์ด์
์๋ต์๋ RSocketRequester.Builder์์ ์ค์ ํด์ผ ํ๋ค. ์์ธํ ๋ด์ฉ์
Client Responders์ ์ฐธ์กฐํ๋ผ.
5.3.3. @MessageMapping
์๋ฒ ๋๋
ํด๋ผ์ด์ธํธ responder ์ค์ ์ด ์๋ฃ๋๋ฉด @MessageMapping ๋ฉ์๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค:
Java:
@Controller
public class RadarsController {
@MessageMapping("locate.radars.within")
public Flux<AirportLocation> radars(MapRequest request) {
// ...
}
}
Kotlin:
@Controller
class RadarsController {
@MessageMapping("locate.radars.within")
fun radars(request: MapRequest): Flow<AirportLocation> {
// ...
}
}
์์ @MessageMapping ๋ฉ์๋๋ โlocate.radars.withinโ ๋ผ์ฐํ
์ ๊ฐ์ง Request-Stream ์ํธ์์ฉ์ ์๋ตํ๋ค. ์ด ๋ฉ์๋๋
๋ค์ ๋ฉ์๋ ์ธ์๋ฅผ ์ฌ์ฉํ๋ ์ ์ฐํ ๋ฉ์๋ ์๊ทธ๋์ฒ๋ฅผ ์ง์ํ๋ค:
| ๋ฉ์๋ ์ธ์ | ์ค๋ช |
|---|---|
@Payload |
์์ฒญ์ ํ์ด๋ก๋. Mono ๋๋ Flux์ ๊ฐ์ด ๋น๋๊ธฐ ํ์
์ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ด ๋ ์ ์๋ค. ์ฐธ๊ณ : ์ด๋ ธํ ์ด์ ์ฌ์ฉ์ ์ ํ์ฌํญ์ด๋ค. ๋จ์ ํ์ ์ด ์๋๋ฉด์ ์ง์๋๋ ์ธ์๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ํ์ด๋ก๋๋ก ๊ฐ์ฃผ๋๋ค. |
RSocketRequester |
์๊ฒฉ ์ข ๋ฃ ์์ฒญ์ ๋ณด๋ธ ์์ฒญ์(requester) |
@DestinationVariable |
๋งคํ ํจํด์ ๋ณ์์ ๊ธฐ๋ฐํ ๋ผ์ฐํ
์ผ๋ก๋ถํฐ ์ถ์ถ๋ ๊ฐ. ์๋ก, @MessageMapping("find.radar.{id}") |
@Header |
๋ฑ๋ก๋ ๋ฉํ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ ๊ฐ. MetadataExtractor ์ฐธ๊ณ |
@Headers Map<String, Object> |
๋ฑ๋ก๋ ๋ชจ๋ ๋ฉํ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ ๊ฐ. MetadataExtractor ์ฐธ๊ณ |
๋ฐํ๊ฐ์ ์๋ต ํ์ด๋ก๋๋ก ์ง๋ ฌํ๋ ํ๋ ์ด์์ ๊ฐ์ฒด๋ก ์์๋๋ค. ๋ฐํ๊ฐ์ Mono ๋๋ Flux์ ๊ฐ์ ๋น๋๊ธฐ ํ์
์ด๊ฑฐ๋, ๊ตฌ์ฒด์ ์ธ ๊ฐ ๋๋
void ๋๋ Mono<Void>์ ๊ฐ์ ๊ฐ์ด ์๋(no-value) ๋น๋๊ธฐ ํ์
์ผ ์ ์๋ค.
@MessageMapping ๋ฉ์๋๊ฐ ์ง์ํ๋ RSocket ์ํธ์์ฉ ํ์
์ ์
๋ ฅ(์: @Payload ์ธ์) ๋ฐ ์ถ๋ ฅ์ ์นด๋๋๋ฆฌํฐ๋ก๋ถํฐ ๊ฒฐ์ ๋๋ค.
์ฌ๊ธฐ์ ์นด๋๋๋ฆฌํฐ๋ ๋ค์์ ์๋ฏธํ๋ค:
| ์นด๋๋๋ฆฌํฐ(Cardinality) | ์ค๋ช |
|---|---|
| 1 | ๋ช
์์ ์ธ ๊ฐ, ํน์ Mono<T>์ ๊ฐ์ ๋จ์ผ๊ฐ(single-value) ๋น๋๊ธฐ ํ์
|
| Many | Flux<T>์ ๊ฐ์ ๋ค์ค๊ฐ(multi-value) ๋น๋๊ธฐ ํ์
|
| 0 | ์
๋ ฅ์์๋ ๋ฉ์๋์ @Payload ์ธ์๊ฐ ์์์ ์๋ฏธํ๋ค. ์ถ๋ ฅ์ ๊ฒฝ์ฐ void ๋๋ Mono<Void>์ ๊ฐ์ ๊ฐ์ด ์๋(no-value) ๋น๋๊ธฐ ํ์
|
๋ค์์ ๋ชจ๋ ์ ๋ ฅ๊ณผ ์ถ๋ ฅ ์นด๋๋๋ฆฌํฐ ์กฐํฉ๊ณผ ๊ทธ์ ๋ฐ๋ฅธ ์ํธ์์ฉ ํ์ ์ ํ์ด๋ค:
| ์
๋ ฅ ์นด๋๋๋ฆฌํฐ (Input Cardinality) |
์ถ๋ ฅ ์นด๋๋๋ฆฌํฐ (Output Cardinality) |
์ํธ๋์ ์ ํ (Interaction Types) |
|---|---|---|
| 0, 1 | 0 | Fire-and-Forget, Request-Response |
| 0, 1 | 1 | Request-Response |
| 0, 1 | Many | Request-Stream |
| Many | 0, 1, Many | Request-Channel |
5.3.4. @ConnectMapping
@ConnectMapping์ RSocket ์ปค๋ฅ์
์์์ SETUP ํ๋ ์์ ํธ๋ค๋งํ๋ค. ๊ทธ๋ฆฌ๊ณ METADATA_PUSH ํ๋ ์
(์: io.rsocket.RSocket์ metadataPush(payload))์ผ๋ก ์ด์ด์ง๋ ๋ฉํ ๋ฐ์ดํฐ ํธ์ ์๋ฆผ์ ํธ๋ค๋งํ๋ค.
@ConnectMapping ๋ฉ์๋๋ @MessageMapping๊ณผ ๋์ผํ ์ธ์๋ฅผ ์ง์ํ์ง๋ง SETUP๊ณผ METADATA_PUSH ํ๋ ์์ ๋ฉํ ๋ฐ์ดํฐ์
๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค. @ConnectMapping์ ํจํด์ ์ง์ ํ๋ฉด ํน์ ๋ผ์ฐํ
์ ๋ณด๊ฐ ์๋ ์ปค๋ฅ์
๋ง ์ฒ๋ฆฌํ๋ค. ์๋ฌด ํจํด๋ ์ ์ธ๋์ง
์์ ๊ฒฝ์ฐ๋ผ๋ฉด ๋ชจ๋ ์ปค๋ฅ์
์ด ๋งค์นญ๋๋ค.
@ConnectMapping ๋ฉ์๋๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ ์ ์์ผ๋ฉฐ void ๋๋ Mono<Void>๋ฅผ ๋ฐํ ํ์
์ผ๋ก ์ ์ธํด์ผ ํ๋ค.
๋ง์ผ ์ ๊ท ์ปค๋ฅ์
์ ๋ํด ์ค๋ฅ๋ฅผ ๋ฐํํ๋ฉด ์ปค๋ฅ์
์ ๊ฑฐ์ ๋๋ค. RSocketRequester์ ์ปค๋ฅ์
์ ์์ฒญํ๊ธฐ ์ํด ์ฒ๋ฆฌ๋ฅผ ๋ณด๋ฅํด์๋
์ ๋๋ค. ์์ธํ ๋ด์ฉ์ Server Requester๋ฅผ ์ฐธ์กฐํ๋ผ.
๋ชฉ์ฐจ ๊ฐ์ด๋