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을 설정할 수 있다.

지원하는 메타 데이터 및 데이터 형식에 필요한 EncoderDecoder 인스턴스를 설정해야 한다. 코덱의 구현은 spring-web 모듈이 필요할 수 있다.

기본적으로 SimpleRouteMatcherAntPathMatcher를 통해 경로 매칭에 사용된다. 효율적인 경로 매칭을 위해 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 요청의 페이로드. 이는 MonoFlux 등의 비동기 유형의 구체적인 값이다. 주의 : 어노테이션 사용은 옵션이다. 단순 형식이 아니라 지원되는 다른 인자 중의 하나가 아니면, 메소드 인수는 예상 페이로드로 간주된다.
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.RSocketmetadataPush(Payload)를 통해 알림을 푸시한다.

@ConnectMapping 메소드는 @MessageMapping과 같은 인수를 지원하고 있지만, SETUP, METADATA_PUSH 프레임에서 메타 데이터와 데이터를 기반으로 한다. @ConnectMapping 메타 데이터 경로를 사용하여 지정된 연결에 처리 수정 패턴을 설정할 수 있다. 패턴이 선언되지 않은 경우 모든 연결이 일치한다.

@ConnectMapping 메소드는 데이터를 반환 할 수 없으며 반환으로 void, Mono<Void>를 사용하여 선언해야 한다. 새 연결에 대한 처리가 오류를 반환하면 연결이 거부된다. 연결에 대한 RSocketRequester 요청을 수행하기 위해 처리를 지연되지 않는다. 자세한 내용은 서버 요청자 를 참조해라.




최종 수정 : 2021-04-12