Spring Web Reactive | 5. RSocket | 5.3. Annotated Responders
RSocket
응답자는 @MessageMapping
와 @ConnectMapping
메소드로 구현할 수 있다. @MessageMapping
메소드는 개별 요청을 처리하고, @ConnectMapping
메소드가 연결 레벨의 이벤트(설치 및 메타 데이터 푸시)를 처리한다. 어노테이션이 선언된 응답자는 서버 사이드에서 응답과 클라이언트 측에서 응답을 위해 대칭적으로 지원된다.
5.3.1. 서버 응답자(Server Responders)
서버 사이드 어노테이션이 선언된 응답자를 사용하려면, RSocketMessageHandler
를 Spring 설정에 추가하여 @MessageMapping
와 @ConnectMapping
메소드에서 @Controller
Bean을 검색한다.
Java
@Configuration
class ServerConfig {
@Bean
fun rsocketMessageHandler() = RSocketMessageHandler().apply {
routeMatcher = PathPatternRouteMatcher()
}
}
Kotlin
@Configuration
class ServerConfig {
@Bean
fun rsocketMessageHandler() = RSocketMessageHandler().apply {
routeMatcher = PathPatternRouteMatcher()
}
}
다음은 Java RSocket API를 사용하여 RSocket 서버를 시작하고 응답자의 RSocketMessageHandler
를 다음과 같이 연결한다.
Java
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))
.awaitSingle()
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))
.awaitSingle()
RSocketMessageHandler
는 기본적으로 복합 메타 데이터와 라우팅 메타 데이터를 지원한다. 다른 MIME 타입으로 전환하거나, 추가 메타 데이터 MIME 유형을 등록해야하는 경우는 MetadataExtractor을 설정할 수 있다.
지원하는 메타 데이터 및 데이터 형식에 필요한 Encoder
와 Decoder
인스턴스를 설정해야 한다. 코덱의 구현은 spring-web
모듈이 필요할 수 있다.
기본적으로 SimpleRouteMatcher
는 AntPathMatcher
를 통해 경로 매칭에 사용된다. 효율적인 경로 매칭을 위해 spring-web
부터 PathPatternRouteMatcher
를 폐쇄하는 것을 권장한다. RSocket 루트는 계층화 할 수 있지만 URL 경로는 없다. 둘 모두 라우트 매처(route matchers)가 “.“을 사용하도록 구성되어 있다. 기본적으로 구분자로 사용되며 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. 클라이언트 응답자
클라이언트 측의 어노테이션이 선언된 응답자는 RSocketRequester.Builder
로 구성해야 한다. 자세한 내용은 클라이언트 응답자를 참조해라.
5.3.3. @MessageMapping
서버 또는 클라이언트 응답자의 설정이 완료되면, @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 |
원격 종료를 요청하는 요청자. |
@DestinationVariable |
매핑 패턴의 변수에 따라 루트에서 추출된 값. @MessageMapping("find.radar.{id}") |
@Header |
MetadataExtractor에서 언급된 추출을 위해 등록된 메타 데이터 값. |
@Headers Map<String, Object> |
MetadataExtractor 따라 추출에 등록된 모든 메타 데이터 값. |
반환 값은 응답 페이로드로 직렬화되는 하나 이상의 오브젝트 일 것으로 예상된다. 이는 Mono
, Flux
와 같은 비동기 타입이거나 구체적인 값 또는 void
, Mono<Void>
와 같은 값이 없는 비동기 타입 중 하나이다.
@MessageMapping
메소드가 지원하는 RSocket 상호 작용 유형은 입력(즉, @Payload
인수)와 출력 카디널리티에서 결정된다. 카디널리티는 다음을 의미한다.
기수 | 설명 |
---|---|
1 | 명시적인 값 또는 Mono<T> 같은 단일 값 비동기 유형 중 하나. |
Many | Flux<T> 등의 여러 값 비동기 타입. |
0 | 입력의 경우,이 메서드에 @Payload 인수가 없음을 의미한다. 출력의 경우, 이는 void , Mono<Void> 와 같은 값이 없는 비동기 유형이다. |
다음 표는 모든 입력 및 출력 중요도의 조합과 대응하는 상호 작용 유형을 보여준다.
입력 카디널리티 | 출력 카디널리티 | 상호 작용 유형 |
---|---|---|
0, 1 | 0 | 단방향 메시지 요청과 응답 |
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
요청을 수행하기 위해 처리를 지연되지 않는다. 자세한 내용은 서버 요청자 를 참조해라.